I do, however, have AES in PowerBASIC code in the form of functions, static and dynamic libraries and standalone GUI's. So, RSA-ECDSA can be augmented fairly quickly by using a PowerBASIC dll.
I decided to open a thread about that dll because you can add AES to any of your own code very easily. I must stress that it only does encryption/decryption for your personal files. It should not be used for sending encrypted data over the internet. For that we should use authenticated encryption. I have PowerBASIC code for that but is not needed for RSA-ECDSA as that is about authentication. Needless to say the dll underwent extensive testing with files of varying lengths and different types of files. It uses a 256KB buffer so we can encrypt files of any size, 6GB if you want.
The dll is easy to use.
AES( <AES strength>, <File>, <password>, <stretch> )
The stretch is an integer employed to inject entropy into a limited entropy password. With <stretch> = 20, for example, we effectively increase the passwords entropy by 20 bits ie make it over one million times stronger (2^20). If the stretching takes 250ms then an attacker, with the same PC power, will only be able to try four guesses of our password per second. The stretch cannot be jumped over because is uses a hash function and a random salt with the final hash being used as our encryption key. The method was got from Cryptography Engineering ISBN: 978-0-470-47424-2.
However, I doubt if anyone is more strongly against using passwords than I am. If, for our password, we used '123456', the most commonly used password at the time of writing, then a dictionary attack, with the above example, would break our code in 250 milliseconds. The reason being that, from a dictionary attack perspective, '123456' has no entropy so stretching it by 20 bits give us 20 bits which even a 1997 laptop would not find intimidating. So, we need to stretch something which has some decent entropy in the first place. I am afraid that I part company with Bruce Schneier on this one.
For small files sizes we can 'push the boat out' with the stretch values but the above argument still holds - with a weak entropy password we will still be 'blown out of the water'. If we stretched for 10 minutes then an attacker would break our code in 10 minutes. It is as simple as that.
The dll, however, will accept binary strings as passwords. For example, if we gave it a 64 random character hex string then the dll will convert that into a 256 binary key. Each byte will have an entropy of 8 bits and so will be saturated. It cannot, therefore, be stretched and so isn't. If we give the dll a stretch value it will be ignored.
Not any old hex string will do: This has to be satisfied ( in PB speak )
Code: Select all
If ( sPassword <> "" ) And ( Len( sPassword ) Mod 2 = 0 ) And ( Len( sPassword ) >= 64 ) And IsTrue Hex( sPassword ) Then
A variety of key derivation functions have been suggested over the years and their principle aim is stretching and provide a key which is uniformly distributed. Well, a random number generator is uniformly distributed so if we generate our hex string with one then it will be uniformly distributed and not requiring any stretching; if the above criteria is satisfied. Obviously I would recommend a CPRNG rather than a PRNG; such as Microsoft's BCryptGenRandom function.
In use, we could have
Code: Select all
AES( AES128, <File>, "E12344C847455AF8F55D9F7E3F2B76A44A034099E824B35A14DBE49C2071D476", 0 )
The following code will generate a cryptographically random 64 character hex string and place it on the clipboard. If you have a password manager then have it open ready to accept the password being Pasted to it because the clipboard will be emptied 10 seconds after the password is created. Even though the clipboard has been emptied the password will still exist in the clipboard manager's database and will need to be removed. If you do not have a password manager then Paste it elsewhere and secure using your current protocol.
HexGen.bas
Code: Select all
#Include once "windows.bi"
#Include Once "win\bcrypt.bi"
#inclib "bcrypt"
' Sub by leopardpm
Sub SaveToClipBoard(Text As String) 'write Text to the clipboard
Var Num=GlobalAlloc(GMEM_MOVEABLE,Len(Text)+1)
memcpy(GlobalLock(num), @text[0], Len(Text)+1)
Var Chars=GlobalLock(Num)
GlobalUnlock(Num)
OpenClipboard(0)
EmptyClipboard()
SetClipboardData(CF_TEXT,Chars)
CloseClipboard()
End Sub
Dim Ss BCRYPT_ALG_HANDLE ptr hRand
Dim As String Password
Dim HexByte( 1 to 64 ) As uByte
Dim As Long i
Dim As Double t
BCryptOpenAlgorithmProvider(@hRand, BCRYPT_RNG_ALGORITHM, 0, 0)
BCryptGenRandom(hRand, @HexByte(1), 64, 0)
BCryptCloseAlgorithmProvider(hRand, 0)
For i = 1 To 64
Password += Mid( "0123456789ABCDEF", HexByte(i)\16 + 1, 1 )
Next
SaveToClipBoard( Password )
Locate 10, 20
Print "Clipboard will be emptied in 10 seconds"
t = timer
Do
Loop Until Timer >= t + 10
OpenClipboard(0)
EmptyClipboard()
CloseClipboard()
Print
Locate 12, 6
Print "If you have a clipboard manager you will have to remove the password"
Sleep
On paper AES256 should be about 30% slower than AES128. When I first looked at AES I was getting more like 20%. However, that is for the encryption time and not the time to read and write data as well. When we look at the whole operation, reading, encrypting and writing then there is very difference between AES128 and AES256. The difference will 'open up' if faster drives are used and I found this to be true when moving tests from my internal HDD to my SSD system drive.
As mentioned the minimum OS requirement is Windows Vista. If you have Windows 7 or later and have AES-NI on your CPU then you will get hardware encryption automatically. If you run CPU-Z you will see AES in the 'Instructions' box if you have AES-NI.
This is what I am getting for a 100MB file. The times are in seconds and each are the average of 10 tests. The filecache was cleared before each test.
Code: Select all
Stretch
0 16 18 20 22
HDD
AES128 0.84 0.89 1.08 1.86 5.00
AES192 0.85 0.90 1.10 1.84 4.97
AES256 0.84 0.88 1.10 1.88 4.97
SSD
AES128 0.34 0.53 0.61 1.37 4.47
AES192 0.41 0.50 0.61 1.40 4.46
AES256 0.35 0.47 0.58 1.36 4.47
Here is a usage example.
Code: Select all
#include once "windows.bi"
const AES128 = 128
const AES192 = 192
Const AES256 = 256
Dim As Any Ptr library = DyLibLoad( "EncDecStretchCNG.dll" )
If library = 0 Then
Print "Failed to load EncDecStretchCNG.dll"
end 1
End If
Dim AES As Function( as long, ByRef as ZString, byref As zString, as long ) as long
AES = DyLibSymbol( library, "EncDecStretchCNG" )
If AES = 0 Then
Print "Could not retrieve the entry point of EncDecStretchCNG"
End 1
End If
' ***** Use your own file *****
Dim As Double t
t = Timer
AES( AES256, "100MB.txt", "0D2D775DEE07C6966E3600851323C9A6C30578B66118D34D7E7130DAA7A6386D", 0 )
t = Timer - t
Print t
print "Done"
sleep
Here is a zip of the library: EncDecStretchCNG.zip
Technical Note:
The header of the encrypted file includes 16 bytes for the random IV (Initial Values) and 32 bytes for the random salt if stretching is employed.