Sign in to follow this  
Followers 0
Ward

Advanced Encryption Standard (AES/Rijndael) UDF

43 posts in this topic

#1 ·  Posted (edited)

After very hard working for two days, the FAST AES UDF finally here. These functions use the embedding DLL technique and the codes are almost all written in low-level language, so it is PURE SCRIPT but run very fast.

For general user, the interface is quite simple:

; To encrypt/decrypt memory block or string:
$Encrypted = _AesEncrypt("Key", "Plantext")
$Decrypted = _AesDecrypt("Key", $Encrypted)
$Result = BinaryToString($Decrypted)

; To encrypt/decrypt file
_AesEncryptFile("Key", $PlantextFilename, $ChipertextFilename)
_AesDecryptFile("Key", $ChipertextFilename, $PlantextFilename)

For advanced user, here are some technical details.

  • The exactly key type of the functions should be 16, 24, or 32 bytes binary. If a string is used, the script just convert it into binary and pad 0x00. To use the binary keys, my MD5 and SHA1/SHA2 hash UDF may be helpful (here and here).

  • For both memory and file functions, there are three block cipher modes include "CBC", "CFB", "OFB" can be specified. For example: (See "What is block cipher modes". BTW, CBC mode use the ciphertext stealing method internally.)

    _AesEncrypt("Key", "Plantext", "CFB")
    _AesDecrypt("Key", $Encrypted, "CFB")
    _AesEncryptFile("Key", $PlantextFilename, $ChipertextFilename, "CFB")
    _AesDecryptFile("Key", $ChipertextFilename, $PlantextFilename, "CFB")

  • _AesEncrypt/_AesDecrypt operate on only one block of memory. If the data to encrypt/decrypt are not continuous, you have to handle all the work by yourself. For example:

    $IV = Binary("0x00000000000000000000000000000000")
    $Ctx = _AesEncryptKey($Key)
    $Ret = _AesCryptOFB($Ctx, $IV, "The quick brown fox ")
    $Ret &= _AesCryptOFB($Ctx, $IV, "jumps over the lazy dog")
    MsgBox(0, '', $Ret)
    
    $IV = Binary("0x00000000000000000000000000000000")
    $Ctx = _AesEncryptKey($Key)
    $Ret = _AesCryptOFB($Ctx, $IV, $Ret)
    MsgBox(0, '', BinaryToString($Ret))

  • CBC/CFB/OFB are different. To use the correct CTX generator and set the correct IV are important. Dig the source in AESTest.au3 may get some inspiration. Here is a summary:

    • CBC mode uses _AesEncryptKey/_AesEncryptCBC to encrpyt and _AesDecryptKey/_AesDecryptCBC to decrypt. But if the length of source < 16 bytes, the IV returned by _AesEncryptCBC should be used. Otherwise, use the same IV as _AesEncryptCBC.
    • CFB mode always uses _AesEncryptKey to generate a CTX, but uses _AesEncryptCFB/_AesDecryptCFB to encrypt/decrypt. However, it always uses the same IV to start.
    • OFB mode is the simplest one. Encryption and decryption are exactly the same. See the example.
    Notice: Although CFB/OFB only use the _AesEncryptKey() to generate a CTX of key, but always regenerate a new CTX before starting to encrypt or decrypt.

  • This library should pass both Known Answer Test and Monte Carlo Test. To try it, download the test vectors from here and remove the comment in AESTest.au3. Have fun!
AES.zip

2008/12/06 Update Note:

Update MemoryDllCall.au3

AES.zip

ECB encrypt/decrypt code in asm by Brian Gladman, other parts by Ward.

Edited by Ward
2 people like this

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites



Hi Ward

Great work. Many thanks for hash functions also.

Share this post


Link to post
Share on other sites

A really good job, I might even use this one if one of my projects ;)

BTW may I ask what dll you used, from what I understand you made the dll yourself?

Share this post


Link to post
Share on other sites

A really good job, I might even use this one if one of my projects :D

BTW may I ask what dll you used, from what I understand you made the dll yourself?

Yes, I made the dll by meself.

I think it's also the smallest dll of AES library (16K after upx). ;)


新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

Yes, I made the dll by meself.

I think it's also the smallest dll of AES library (16K after upx). :P

What a nice piece of code, you really did good :(

Share this post


Link to post
Share on other sites

Hi,

first of all this is a greate script, the file_encrypt works great but i seem to have a little problem.

i built a program that that keeps the settings stored in a txt file delimitered by "," for example "ftp_srvr,user,password,pass" and with your UDF i am now able to keep the file encrypted using file encrypt but when i want to read it into the app i need to decrypt the file to the hard drive and then read it and i dont want to, so i used _Aesencrypt to encript the data and then write it to the file when it is already encrypted and then read it encrypted and decrypt it inside my app, when i decrypt it once it comes out fine but if i do the encrypt\decrypt a few times even without changing the data the data gets lost.

this is a code that works on a file called "data" that contains "aa,aa,aa,aa" in one row, it reads the data,encrypt it and then decrypt it.

after a few times it simply gets ruined! am i doing something wrong?

#Include "aes.au3"
#Include "file.au3"

global $data_array,$unencripted_data
$key=Binary("0x01000111010000001001001000111101")


$Fileinput = @ScriptDir&"\data"

_FileReadToArray ($Fileinput,$data_array)

$unencripted_data=$data_array[1]

ConsoleWrite ("the unencrypted data is : "&$unencripted_data&@CRLF)
$encrypted_data=_Aesencrypt($key, $unencripted_data)
ConsoleWrite ("   the encrypted data is : "&$encripted_data&@CRLF)
FileDelete ($Fileinput)

filewriteline ($Fileinput,$encripted_data)

;-----------end of part one----------------------


_FileReadToArray ($Fileinput,$data_array)
;$data_array[1]=binary("0xFB5B7E5A6B1BA7C460E779BC10FBD514318DABEAAE4603E96F4EEFBD8853B6714AAB507E006ADFAC")
$unencripted_data=_Aesdecrypt($key, $data_array[1])
;MsgBox (0,"",BinaryToString($unencripted_data))
$data_array=stringsplit ($unencripted_data,",")
ConsoleWrite ("the unenrcypted data is : "&BinaryToString($unencripted_data)&@CRLF)
FileDelete($Fileinput)
fileopen ($fileinput,1)
_FileWriteToLine($Fileinput,1,BinaryToString($unencripted_data),1)
FileClose($fileinput)

Share this post


Link to post
Share on other sites

You should read the encrypted data as binary mode, try this code

#Include "aes.au3"

; Part 1 - To save the password
$PlainText = "name,password,ip"
$Key = "ThisIsTheKey"
$Data = _AesEncrypt($Key, $PlainText)

$File = FileOpen("data", 2)
FileWrite($File, $Data)
FileClose($File)

; Part 2 - To load the password
$File = FileOpen("data", 16)
$Data = FileRead($File)
FileClose($File)

$Key = "ThisIsTheKey"
$PlainText = _AesDecrypt($Key, $Data)
ConsoleWrite($PlainText)

FileDelete("data")

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

You should read the encrypted data as binary mode, try this code

#Include "aes.au3"

; Part 1 - To save the password
$PlainText = "name,password,ip"
$Key = "ThisIsTheKey"
$Data = _AesEncrypt($Key, $PlainText)

$File = FileOpen("data", 2)
FileWrite($File, $Data)
FileClose($File)

; Part 2 - To load the password
$File = FileOpen("data", 16)
$Data = FileRead($File)
FileClose($File)

$Key = "ThisIsTheKey"
$PlainText = _AesDecrypt($Key, $Data)
ConsoleWrite($PlainText)

FileDelete("data")
My good friend it worked like a charm! a thousand thanks!!!!

The best "FAST UDF" ever!

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Hi Ward. Thanks for the UDF. I've had a lot of fun lately playing around with the various encryption functions I've been finding on the forums.

Sorry if this is post is too old to be relevant anymore, but I'm having a minor/fixable issue with the main encryption function.

_AesEncrypt($Key, $Data, $Mode = $AES_CBC_MODE, $IV = Default)

I'm encrypting text with the following:

$Text = _AesEncrypt($Key, $Text)

This should leave the function assuming $Mode = $AES_CBC_MODE and an automatically generating $IV. In this case, it is encrypting the text using CFB mode instead.

Switch $Mode
    Case "Bananas"  ; Added this for testing. This always is the Case when no $Mode is given with the function call
        Return "Bananas"
            
    Case "CFB", $AES_CFB_MODE
        ConsoleWrite("CFB" & @CR)
        $Ret = _AesEncryptCFB($AesCtx, $IV, $Data)
        $AesCtx = 0
        If BinaryLen($Ret) = 0 Then Return SetError(1, 0, "")
        Return $IVBackup & $Ret

    Case "OFB", $AES_OFB_MODE
        ConsoleWrite("OFB" & @CR)
        $Ret = _AesCryptOFB($AesCtx, $IV, $Data)
        $AesCtx = 0
        If BinaryLen($Ret) = 0 Then Return SetError(1, 0, "")
        Return $IVBackup & $Ret

    Case Else
        ConsoleWrite("Else" & @CR)
        $Ret = _AesEncryptCBC($AesCtx, $IV, $Data)
        $AesCtx = 0
        If BinaryLen($Ret) = 0 Then Return SetError(1, 0, "")
        If BinaryLen($Data) <  16 Then Return $IV & $Ret
        Return $IVBackup & $Ret

EndSwitch

I assume this is happening because $AES_CBC_MODE = 0 and (0 = "Bananas") returns True ('Case "CFB", $AES_CFB_MODE' is also true when 'Case "Bananas"' is removed).

The easy way to work around this was to specify $Mode when calling the function, even when deciding to use the default CBC method.

Edited by Vakari

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Hi,

First of all thanks for your amazing work... It works and it works fasts :D... It's very cool :o

I have a question though. It may be a dumb one but what is the IV constant in your script?

What does it do?

Thanks in advance

Edited by tip

[center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center]

Share this post


Link to post
Share on other sites

Jrowe thank you for your quick reply but I'm not very good at programing and I'm worse at cryption. Can you help me understand initialization vector?

Does it works LIKE-in a way- a second enrcyption key?

Does the function automatically define an IV or do I get to define it?

If so when I define the IV is it more secure?

And one last thing -not about IV- is there a way to make a progress bar with this? I thought about reading encrypted files size and compare it to the original files size but I'm not sure AES algorithm gives a same size of file as the orijinal...:D

Thanks in advance


[center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center]

Share this post


Link to post
Share on other sites

Jrowe thank you for your quick reply but I'm not very good at programing and I'm worse at cryption. Can you help me understand initialization vector?

Does it works LIKE-in a way- a second enrcyption key?

Does the function automatically define an IV or do I get to define it?

If so when I define the IV is it more secure?

And one last thing -not about IV- is there a way to make a progress bar with this? I thought about reading encrypted files size and compare it to the original files size but I'm not sure AES algorithm gives a same size of file as the orijinal...^_^

Thanks in advance

When compiling the example I get: ERROR: undefined macro for @AutoItUnicode, how to solve this? @Unicode generates an error too.

Share this post


Link to post
Share on other sites

When compiling the example I get: ERROR: undefined macro for @AutoItUnicode, how to solve this? @Unicode generates an error too.

Replace @AutoItUnicode with for examle $AutoItUnicode and add
$AutoItUnicode = True
on top of your script.

Or remove @AutoItUnicode conditions from the script, or just hit Continue anyway.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Hi Ward,

first of all I would like to thank you for the very nice work. >_<

Today I was just playing around with your UDFs and I noticed that the "_AesEncryptKey" function returns an empty string!!!

I tried something like this:

$Key = "TestKey"

$Ctx = _AesEncryptKey($Key)

MsgBox(0, "EncrKey", $Ctx)

As mentioned above $Ctx is empty!!!

Have you any ideas concerning this problem???

Thanks in advance,

Biblos

Share this post


Link to post
Share on other sites

It is not a problem. Look at the UDF source. $Ctx is a DllStruct, not a string.

Share this post


Link to post
Share on other sites

Hi,

I tried it and it worked really fast.

But one question: I tried to encrypt a Rar File with 128MB. It worked.

Then I tried to decrypt it and got an error "Out of memory".

(Laptop with XP and 1GB Ram and I used _AesExit() for encryption and decryption)

Does decryption need more memory then encryption?

How much memory do I need to en/decrypt a file?

Is there any tooling to defragment memory?

I know that 1GB is not much for Windows and I could buy more memory.

But what happens if I want to encrypt files with 500MB or bigger?

many thanks.

Share this post


Link to post
Share on other sites

Ward, I got a question about how your _AesDecrypt func works. Can you explain the magic behind decrypting ciphertext without knowing the IV used to generate the ciphertext? Any chance you are able to share the ASM source for the DLL?

Share this post


Link to post
Share on other sites

Ward,

Seems this is a old post but I having been working with you script UDF, and found a issue I need some assistance with.

If I encrypt and decrypt in the same func it works correctly look at AES_Encrypt where I call AES_Decrypt after I encrypt the data. If I store the encrypted data and retrieve it from storage and use only the AES_Decrypt Func the data I get is garbage.

logs from my script:

2009-12-09 20:30:38 : fleminr Selected to Enroll Challenge and Response questions.

2009-12-09 20:30:57 : fleminr Binary Input Data : 0x79756361697061

2009-12-09 20:30:57 : fleminr Encrypting Data : 0x33496FFF6F775A299D5FD261084397837F7DEF144CC52C

2009-12-09 20:30:57 : fleminr Decrypted input : 0x33496FFF6F775A299D5FD261084397837F7DEF144CC52C

2009-12-09 20:30:57 : fleminr Decrypted output1 : 0x79756361697061

2009-12-09 20:30:57 : fleminr Decrypted output2 : yucaipa

2009-12-09 20:30:57 : fleminr Encrypted answer was sent to Directory. : 0x33496FFF6F775A299D5FD261084397837F7DEF144CC52C

2009-12-09 20:30:57 : fleminr Binary Input Data : 0x677265656E

2009-12-09 20:30:57 : fleminr Encrypting Data : 0x2896D3C949AFA21E156BEAE75EFDBE1E283ABF8741

2009-12-09 20:30:57 : fleminr Decrypted input : 0x2896D3C949AFA21E156BEAE75EFDBE1E283ABF8741

2009-12-09 20:30:57 : fleminr Decrypted output1 : 0x677265656E

2009-12-09 20:30:57 : fleminr Decrypted output2 : green

2009-12-09 20:30:57 : fleminr Encrypted answer was sent to Directory. : 0x2896D3C949AFA21E156BEAE75EFDBE1E283ABF8741

2009-12-09 20:30:57 : fleminr Binary Input Data : 0x6D6F726C6579

2009-12-09 20:30:57 : fleminr Encrypting Data : 0x7E7E75714ED64E5B0CC1A0D42E8DEEBEDE529DE0AD21

2009-12-09 20:30:57 : fleminr Decrypted input : 0x7E7E75714ED64E5B0CC1A0D42E8DEEBEDE529DE0AD21

2009-12-09 20:30:57 : fleminr Decrypted output1 : 0x6D6F726C6579

2009-12-09 20:30:57 : fleminr Decrypted output2 : morley

2009-12-09 20:30:57 : fleminr Encrypted answer was sent to Directory. : 0x7E7E75714ED64E5B0CC1A0D42E8DEEBEDE529DE0AD21

2009-12-09 20:30:58 : fleminr Submitted Challenge Questions and Answers

2009-12-09 20:31:04 : fleminr Selected 'Forgot My Password option.

2009-12-09 20:31:05 : fleminr Users encrypted answer was retrieved from Directory. : 0x33496FFF6F775A299D5FD261084397837F7DEF144CC52C

2009-12-09 20:31:05 : fleminr Users encrypted answer was retrieved from Directory. : 0x2896D3C949AFA21E156BEAE75EFDBE1E283ABF8741

2009-12-09 20:31:05 : fleminr Users encrypted answer was retrieved from Directory. : 0x7E7E75714ED64E5B0CC1A0D42E8DEEBEDE529DE0AD21

2009-12-09 20:31:14 : fleminr Decrypted input : 0x33496FFF6F775A299D5FD261084397837F7DEF144CC52C<--- This is the same yet does not generate the same decrypted out put

2009-12-09 20:31:14 : fleminr Decrypted output1 : 0x3A101F87EBD4312B1D0201A5D13E1D5CB87619D4E2CC724F241F9D113111EB23F4<---does not match previous

2009-12-09 20:31:14 : fleminr Decrypted output2 : :‡ëÔ1+¥Ñ>\¸vÔâÌrO$1ë#ô <---Garbage

Func AES_Encrypt($userid,$data)

$bindata = Binary($data)

_FileWriteLog("\\10.240.52.109\Log\SSPP.log",$userid&" "&"Binary Input Data"&" : "&$bindata)

$Encrypted = _AesEncrypt("95A8EE8E89979B9EFDCBC6EB9797528D432DC26061553818EA635EC5D5A7727E", $bindata, "CBC")

_FileWriteLog("\\10.240.52.109\Log\SSPP.log",$userid&" "&"Encrypting Data"&" : "&$Encrypted)

AES_Decrypt($userid,$Encrypted)

Return $Encrypted

EndFunc

Func AES_Decrypt($userid,$data)

_FileWriteLog("\\10.240.52.109\Log\SSPP.log",$userid&" "&"Decrypted input"&" : "&$data)

$Decrypted = _AesDecrypt("95A8EE8E89979B9EFDCBC6EB9797528D432DC26061553818EA635EC5D5A7727E", $data, "CBC")

_FileWriteLog("\\10.240.52.109\Log\SSPP.log",$userid&" "&"Decrypted output1"&" : "&$Decrypted)

$Result = BinaryToString($Decrypted)

_FileWriteLog("\\10.240.52.109\Log\SSPP.log",$userid&" "&"Decrypted output2"&" : "&$Result)

Return $Result

EndFunc

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0