Page 4 of 5
Posted: Sat Aug 14, 2004 3:25 pm
by newbie
@blueb
Sec lib + source code example of how to use it with strings has been posted.
Now Max is trying with his Lib (different than Sec's Lib) to do file encryption, and as soon as the code will be working, we'll convert it to Sec's lib, so everyone could use the code whatever the Lib they are using
The Max lib link is just above.
@Max
I tried with C:\Windows\system32\alg.exe, :
http://perso.wanadoo.fr/jugesoftware/purebasic/alg.zip
the executable is 40Kb.
Posted: Sat Aug 14, 2004 3:47 pm
by Max.²
Works here without any problem. It isn't padded at all, as it is a multiple of 16 and MD5FileFingerprint says that original and decrypted are identical.
Posted: Sat Aug 14, 2004 4:19 pm
by newbie
does not work for me, the debug MD5 thing said error and the file is smaller
how is it possible ?
EDIT :

Posted: Sat Aug 14, 2004 4:40 pm
by Max.²
You are using
- the latest code (updated in the posting; I am wondering because there should be more debug messages)
- alg.exe is not write protected
?
What are the file sizes for
1. the original
2. the encrypted
3. the decrypted
?
BTW, I just tried 2500 files, from 1 byte to several GB, ascii & binary, without any problem.
Posted: Sat Aug 14, 2004 4:49 pm
by newbie
Ok it works
Last time you said to use your updated code, I done it, but you have updated it once again later (your post has been edited twice) :-/
Let me trying to convert it to Sec's Lib, and I'll post both on my homepage, good work !
EDIT : unless you can do it :roll:

Posted: Sat Aug 14, 2004 5:27 pm
by newbie
your code converted to use Sec's Lib :
Code: Select all
;http://www.host4scripts.de/pub/AESLIB.zip ; use just _1_ of the libs
;to make life easier, FileReadBufferSize needs to be a multiplier of 16
;Key is meant hexademical. A common way to generate a 16 byte key out of a password is to use MD5Fingerprint
Procedure AES_Crypt_File(Mode,InFilename.s,OutFileName.s,key.s,FileReadBufferSize)
;Mode 0 = Encrypt
;Mode 1 = Decrypt
If FileReadBufferSize % 16 = 0
#OutFile = 0
#InFile = 1
FileIn=OpenFile(#InFile,InFilename.s)
If FileIn<>0
AES256Init(@key)
*InputBuffer = AllocateMemory(FileReadBufferSize)
*OutputBuffer = AllocateMemory(FileReadBufferSize)
*PlainBlock = AllocateMemory(16)
*EncryptionBlock = AllocateMemory(16)
FileLength = FileSize(InFilename)
BlocksToRead = Int(FileLength/FileReadBufferSize)
Result=CreateFile(#OutFile,OutFileName)
If Result
For Offset = 0 To BlocksToRead
If Offset<BlocksToRead
BlockSize = FileReadBufferSize
Else
BlockSize = FileLength-Offset*FileReadBufferSize
EndIf
; get data from input file
UseFile(1)
FileSeek(Offset*FileReadBufferSize)
Result=ReadData(*InputBuffer,BlockSize)
;Pad (make multiple of 16bytes) if needed
If BlockSize<>FileReadBufferSize And Mode = 0
Debug "Pad!"
PadBytes = (FileReadBufferSize - BlockSize) % 16
Debug "Need to pad with "+Str(PadBytes)+" bytes"
For i=0 To PadBytes-1
;Using pad method RFC2630
PokeB(*InputBuffer+BlockSize+i,PadBytes)
Next i
BlockSize = BlockSize + PadBytes
EndIf
; write data to outputfile
UseFile(0)
For EncryptionBlockOffset = 0 To FileReadBufferSize / 16
CopyMemory(*InputBuffer+EncryptionBlockOffset*16, *PlainBlock , 16)
If Mode = 0
*EncryptionBlock = AES256Encrypt(*PlainBlock)
ElseIf Mode = 1
*EncryptionBlock = AES256Decrypt(*PlainBlock)
EndIf
CopyMemory(*EncryptionBlock,*OutputBuffer+EncryptionBlockOffset*16,16)
Next EncryptionBlockOffset
FileSeek(Offset*FileReadBufferSize)
;Strip padded bytes
If Mode=1 And ((Offset = BlocksToRead) Or (FileLength % FileReadBufferSize = 0))
Debug "Unpad!"
PaddedBytes=PeekB(*OutputBuffer+BlockSize-1) & $FF
Debug "Supposed # of padded bytes: "+Str(PaddedBytes)
For i=1 To PaddedBytes
If PeekB(*OutputBuffer+BlockSize-i)<>PaddedBytes
Debug "False alarm. No unpadding needed."
Break
EndIf
Next i
If i>PaddedBytes And PaddedBytes<16
BlockSize=BlockSize-PaddedBytes
Debug "Decreasing Block by "+Str(PaddedBytes)+" to get rid of padded bytes"
EndIf
EndIf
WriteData(*OutputBuffer,BlockSize)
Next Offset
CloseFile(#InFile)
CloseFile(#OutFile)
EndIf
FreeMemory(-1)
EndIf
Else
Error = 1
EndIf
EndProcedure
start = GetTickCount_()
key.s = "00010203050607080A0B0C0D0F101112"
InFile.s = "c:\alg.exe"
EncryptFile.s = "c:\alg.enc"
DecryptFile.s = "c:\alg_dec.exe"
AES_Crypt_File(0,InFile.s,EncryptFile.s,key.s,8192*2)
AES_Crypt_File(1,EncryptFile.s,DecryptFile.s,key.s,8192*2)
Debug "Milliseconds: "+Str(GetTickCount_()-start)
If MD5FileFingerprint(InFile) = MD5FileFingerprint(DecryptFile)
Debug "ok"
Else
Debug "error"
EndIf
works for me, is it ok with you ?
As soon as it's ok, I'll post both, by saying of course that it's your work, obviously

Posted: Sat Aug 14, 2004 5:50 pm
by newbie
What about this ?
I added compression.
So the file to encrypt is first packed, then encrypted, then decrypted, then unpacked :
Code: Select all
;http://www.host4scripts.de/pub/AESLIB.zip ; use just _1_ of the libs
;to make life easier, FileReadBufferSize needs to be a multiplier of 16
;Key is meant hexademical. A common way to generate a 16 byte key out of a password is to use MD5Fingerprint
Procedure AES_Crypt_File(Mode,InFilename.s,OutFileName.s,key.s,FileReadBufferSize)
;Mode 0 = Encrypt
;Mode 1 = Decrypt
If FileReadBufferSize % 16 = 0
#OutFile = 0
#InFile = 1
If Mode = 0
packed_filename.s = InFilename + ".pack"
res = CreatePack(packed_filename)
If res <> 0
; 9 = MAX compression
res = AddPackFile(InFilename , 9)
ClosePack()
Else
Debug "error while packing"
ProcedureReturn
EndIf
EndIf
InFilename = packed_filename
FileIn=OpenFile(#InFile,InFilename.s)
If FileIn<>0
AES256Init(@key)
*InputBuffer = AllocateMemory(FileReadBufferSize)
*OutputBuffer = AllocateMemory(FileReadBufferSize)
*PlainBlock = AllocateMemory(16)
*EncryptionBlock = AllocateMemory(16)
FileLength = FileSize(InFilename)
BlocksToRead = Int(FileLength/FileReadBufferSize)
Result=CreateFile(#OutFile,OutFileName)
If Result
For Offset = 0 To BlocksToRead
If Offset<BlocksToRead
BlockSize = FileReadBufferSize
Else
BlockSize = FileLength-Offset*FileReadBufferSize
EndIf
; get data from input file
UseFile(1)
FileSeek(Offset*FileReadBufferSize)
Result=ReadData(*InputBuffer,BlockSize)
;Pad (make multiple of 16bytes) if needed
If BlockSize<>FileReadBufferSize And Mode = 0
Debug "Pad!"
PadBytes = (FileReadBufferSize - BlockSize) % 16
Debug "Need to pad with "+Str(PadBytes)+" bytes"
For i=0 To PadBytes-1
;Using pad method RFC2630
PokeB(*InputBuffer+BlockSize+i,PadBytes)
Next i
BlockSize = BlockSize + PadBytes
EndIf
; write data to outputfile
UseFile(0)
For EncryptionBlockOffset = 0 To FileReadBufferSize / 16
CopyMemory(*InputBuffer+EncryptionBlockOffset*16, *PlainBlock , 16)
If Mode = 0
*EncryptionBlock = AES256Encrypt(*PlainBlock)
ElseIf Mode = 1
*EncryptionBlock = AES256Decrypt(*PlainBlock)
EndIf
CopyMemory(*EncryptionBlock,*OutputBuffer+EncryptionBlockOffset*16,16)
Next EncryptionBlockOffset
FileSeek(Offset*FileReadBufferSize)
;Strip padded bytes
If Mode=1 And ((Offset = BlocksToRead) Or (FileLength % FileReadBufferSize = 0))
Debug "Unpad!"
PaddedBytes=PeekB(*OutputBuffer+BlockSize-1) & $FF
Debug "Supposed # of padded bytes: "+Str(PaddedBytes)
For i=1 To PaddedBytes
If PeekB(*OutputBuffer+BlockSize-i)<>PaddedBytes
Debug "False alarm. No unpadding needed."
Break
EndIf
Next i
If i>PaddedBytes And PaddedBytes<16
BlockSize=BlockSize-PaddedBytes
Debug "Decreasing Block by "+Str(PaddedBytes)+" to get rid of padded bytes"
EndIf
EndIf
WriteData(*OutputBuffer,BlockSize)
Next Offset
CloseFile(#InFile)
CloseFile(#OutFile)
If Mode = 1
packed_filename.s = OutFileName
res = OpenPack(packed_filename)
If res <> 0
*addr = NextPackFile()
size = PackFileSize()
File = OpenFile(#InFile, packed_filename)
WriteData(*addr, size)
CloseFile(#InFile)
ClosePack()
Else
Debug "error while unpacking"
ProcedureReturn
EndIf
EndIf
EndIf
FreeMemory(-1)
EndIf
Else
Error = 1
EndIf
EndProcedure
start = GetTickCount_()
key.s = "00010203050607080A0B0C0D0F101112"
InFile.s = "c:\alg.exe"
EncryptFile.s = "c:\alg.enc"
DecryptFile.s = "c:\alg_dec.exe"
AES_Crypt_File(0,InFile.s,EncryptFile.s,key.s,8192*2)
AES_Crypt_File(1,EncryptFile.s,DecryptFile.s,key.s,8192*2)
Debug "Milliseconds: "+Str(GetTickCount_()-start)
If MD5FileFingerprint(InFile) = MD5FileFingerprint(DecryptFile)
Debug "ok"
Else
Debug "error"
EndIf
I like it

Posted: Sat Aug 14, 2004 6:37 pm
by Max.²
newbie wrote:your code converted to use Sec's Lib :
works for me, is it ok with you ?
As soon as it's ok, I'll post both, by saying of course that it's your work, obviously

It works, but not as supposed.
2 problems, both key related.
1. a key like "00010203050607080A0B0C0D0F101112" is meant to be the hexadecimal representation of the key. In this case
00
01
02
03
...
11
12 (= decimal 18 )
So you need to poke the decimal value in each byte:
This is why I used this bit of code:
Code: Select all
;Key transformation
*KeyBuffer = AllocateMemory(16)
j=-1
For i=1 To Len(Key.s) Step 2
j=j+1
;Poking Hex key into buffer
PokeB(*KeyBuffer+j,Hex2Dec(Mid(Key,i,2)))
Next i
2. The keylength is according to the encryption strength. I am using variable keys in my sample, with the key string of 32 characters using 128bit encryption. You need to use a 64bit long key, else the results can differ.
(I just saw that I falsely limited the keybuffer to 128bit; that is wrong, too)
Compression I like in conjunction with encryption especially. Bad thing is that it often breaks compatibility (which isn't really given in AES anyway, so no biggy).
Posted: Sat Aug 14, 2004 8:59 pm
by newbie
Thanks MAx for the Tip, I just found that in fact I have the same problem anywhere in my program.
So I should do the same for Blowfish using Sec's lib ?
Code: Select all
temp = MD5...
temp = left(temp, 10)
*KeyBuffer = AllocateMemory(5) ; 40 bits key
j=-1
For i=1 To Len(temp) Step 2
j=j+1
PokeB(*KeyBuffer+j,hex2dec(Mid(temp,i,2)))
Next i
bfinit(*KeyBuffer, 5)
What is the difference in terms of security between giving the string against giving the hex ?
Posted: Sat Aug 14, 2004 9:08 pm
by CherokeeStalker
thefool wrote:Hi
I was just wandering around the forum and i found this post, and i just wanted to ask:
Whats the best encryption? Aes or RC4?
AES aka Rijndael is the latest standard !
Posted: Sat Aug 14, 2004 9:35 pm
by Max.²
newbie wrote:Thanks MAx for the Tip, I just found that in fact I have the same problem anywhere in my program.
So I should do the same for Blowfish using Sec's lib ?
Code: Select all
temp = MD5...
temp = left(temp, 10)
*KeyBuffer = AllocateMemory(5) ; 40 bits key
j=-1
For i=1 To Len(temp) Step 2
j=j+1
PokeB(*KeyBuffer+j,hex2dec(Mid(temp,i,2)))
Next i
bfinit(*KeyBuffer, 5)
What is the difference in terms of security between giving the string against giving the hex ?
It depends on the lib; a lib could implement another way to pass a key; but likely for the Blowfish lib it is the same.
For security, I don't see any problem*, but for the interoperability. There are several test vectors available for the different encryptions and they should of course lead to the same result.
I think, best is to use the "right" approach, even if it looks awkward. And to use test vectors to confirm.
*problem is if you just pass values out of the hex number range ( "0123456789ABCDEF"). That limits the encryption. If you pass it directly, but use a key string like "TheQuickBrownFox", then it should be safe. But not interoperable.
Posted: Sun Aug 15, 2004 5:07 am
by sec
I have update get at
http://metawire.org/~sec/aesv3.zip (it is going down i will upload as soon as possible expect somebody can give me some host space

) sha1 hash has done some mins ago
PS: newbie, compress data before encryption is good idea

Key in format (hex, base64, or blah) is not important, 'what' i&you would know "bits range of key that algorithm support".
Even, i saw a one-pad algo that key generate from audio interface

Posted: Sun Aug 15, 2004 11:30 am
by newbie
Sec :
About the compresssion, since my prog sends files via the network, it is very usefull, nice to see a built-in packer in PB.
About your AESV3, I have some web space, send me the file !

Again, what are the modifications ?
And about SHA... can't wait for it !
EDIT : the AES ecnryption file updated :
Code: Select all
;http://www.host4scripts.de/pub/AESLIB.zip ; use just _1_ of the libs
;to make life easier, FileReadBufferSize needs to be a multiplier of 16
;Key is meant hexademical. A common way to generate a 16 byte key out of a password is to use MD5Fingerprint
;Procedure by PB / english forum
Procedure.l hex2dec(h$)
h$=UCase(h$)
For r=1 To Len(h$)
d<<4 : a$=Mid(h$,r,1)
If Asc(a$)>60
d+Asc(a$)-55
Else
d+Asc(a$)-48
EndIf
Next
ProcedureReturn d
EndProcedure
Procedure AES_Crypt_File(Mode, InFilename.s, OutFileName.s, key.s, FileReadBufferSize)
;Mode 0 = Encrypt
;Mode 1 = Decrypt
If FileReadBufferSize % 16 = 0
#OutFile = 0
#InFile = 1
If Mode = 0
packed_filename.s = InFilename + ".pack"
res = CreatePack(packed_filename)
If res <> 0
; 9 = MAX compression
res = AddPackFile(InFilename , 9)
ClosePack()
Else
Debug "error while packing"
ProcedureReturn
EndIf
InFilename = packed_filename
EndIf
FileIn=OpenFile(#InFile,InFilename.s)
If FileIn<>0
;Key transformation
*KeyBuffer = AllocateMemory(32)
key = key + key ; key is a MD5 128 bits key, we need 256 bits for AES 256, it's a workaround until we have SHA-256
Debug "key = " + key
j=-1
For i=1 To Len(key) Step 2
j=j+1
PokeB(*KeyBuffer+j,hex2dec(Mid(key,i,2)))
Next i
AES256Init(*KeyBuffer)
*InputBuffer = AllocateMemory(FileReadBufferSize)
*OutputBuffer = AllocateMemory(FileReadBufferSize)
*PlainBlock = AllocateMemory(16)
*EncryptionBlock = AllocateMemory(16)
FileLength = FileSize(InFilename)
BlocksToRead = Int(FileLength/FileReadBufferSize)
Result=CreateFile(#OutFile,OutFileName)
If Result
For Offset = 0 To BlocksToRead
If Offset<BlocksToRead
BlockSize = FileReadBufferSize
Else
BlockSize = FileLength-Offset*FileReadBufferSize
EndIf
; get data from input file
UseFile(1)
FileSeek(Offset*FileReadBufferSize)
Result=ReadData(*InputBuffer,BlockSize)
;Pad (make multiple of 16bytes) if needed
If BlockSize<>FileReadBufferSize And Mode = 0
Debug "Pad!"
PadBytes = (FileReadBufferSize - BlockSize) % 16
Debug "Need to pad with "+Str(PadBytes)+" bytes"
For i=0 To PadBytes-1
;Using pad method RFC2630
PokeB(*InputBuffer+BlockSize+i,PadBytes)
Next i
BlockSize = BlockSize + PadBytes
EndIf
; write data to outputfile
UseFile(0)
For EncryptionBlockOffset = 0 To FileReadBufferSize / 16
CopyMemory(*InputBuffer+EncryptionBlockOffset*16, *PlainBlock , 16)
If Mode = 0
*EncryptionBlock = AES256Encrypt(*PlainBlock)
ElseIf Mode = 1
*EncryptionBlock = AES256Decrypt(*PlainBlock)
EndIf
CopyMemory(*EncryptionBlock,*OutputBuffer+EncryptionBlockOffset*16,16)
Next EncryptionBlockOffset
FileSeek(Offset*FileReadBufferSize)
;Strip padded bytes
If Mode=1 And ((Offset = BlocksToRead) Or (FileLength % FileReadBufferSize = 0))
Debug "Unpad!"
PaddedBytes=PeekB(*OutputBuffer+BlockSize-1) & $FF
Debug "Supposed # of padded bytes: "+Str(PaddedBytes)
For i=1 To PaddedBytes
If PeekB(*OutputBuffer+BlockSize-i)<>PaddedBytes
Debug "False alarm. No unpadding needed."
Break
EndIf
Next i
If i>PaddedBytes And PaddedBytes<16
BlockSize=BlockSize-PaddedBytes
Debug "Decreasing Block by "+Str(PaddedBytes)+" to get rid of padded bytes"
EndIf
EndIf
WriteData(*OutputBuffer,BlockSize)
Next Offset
CloseFile(#InFile)
CloseFile(#OutFile)
If Mode = 1
packed_filename.s = OutFileName
res = OpenPack(packed_filename)
If res <> 0
*addr = NextPackFile()
size = PackFileSize()
File = OpenFile(#InFile, packed_filename + ".dec")
WriteData(*addr, size)
CloseFile(#InFile)
ClosePack()
Else
Debug "error while unpacking"
ProcedureReturn
EndIf
EndIf
EndIf
FreeMemory(-1)
EndIf
Else
Error = 1
EndIf
EndProcedure
start = GetTickCount_()
key.s = MD5Fingerprint("toto", 4)
InFile.s = "c:\alg.exe"
EncryptFile.s = "c:\alg.enc"
DecryptFile.s = "c:\alg.dec.exe"
AES_Crypt_File(0, InFile, EncryptFile, key, 8192*2)
AES_Crypt_File(1, EncryptFile, DecryptFile, key, 8192*2)
DeleteFile(DecryptFile)
RenameFile(DecryptFile + ".dec", DecryptFile)
Debug "Milliseconds: "+Str(GetTickCount_()-start)
If MD5FileFingerprint(InFile) = MD5FileFingerprint(DecryptFile)
Debug "ok"
Else
Debug "error"
EndIf
I fill the key in the good way know, and packing+encryption/decryption+unpacking is working fine

Posted: Sun Aug 15, 2004 7:24 pm
by Max.²
And about SHA... can't wait for it !
If you can't wait, you might want to try out this:
http://www.host4scripts.de/pub/SHA
Example:
Code: Select all
;expected a9993e364706816aba3e25717850c26c9cd0d89d
;generic
Hash.s=Space(255)
Input.s = "abc"
SHA1(@Hash,@Input,Len(Input))
For i=1 To 20
Debug Hex(PeekB(@Hash+i-1)& $ff)
Next i
;easy mode
Result.s = SHA1Fingerprint("abc")
Debug Result
There are more functions, but it's time for dinner. Hope it works for you!
Posted: Sun Aug 15, 2004 7:37 pm
by newbie
Thanks Max I will try it, but I thought that Sec was working on this one, we will have two same Libs again :-/
You should PM you and agree about who does what
such as , Max :
SHA-1 / SHA-256
Sec :
SHA-384 (is it the good one ?)
SHA-512
I have always liked multitasking ^^
Anyway, downloading your Lib right now
EDIT : why the SHA library is so huge (20.3Ko) against only 9Ko for AES ? I would have thought that AES would have been far bigger than a hash algorithm.
Then the function SHA1Fingerprint is buggy, see the screenshot :
The final '9D' is moved first :-/