AutoHotkey Community

It is currently May 27th, 2012, 5:14 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: May 20th, 2008, 5:08 am 
After reading the post below, I tried to write this one. HTH.
http://www.autohotkey.com/forum/topic31 ... 5275e974dd

Code:
sTextOriginl := "These are a few tests of AES Encryption/Decryption!"
sPassword  := "AutoHotkey"

SID := 128   ; 128bit AES
nSize := Text_AES(sTextEncrypt, &sTextOriginl, StrLen(sTextOriginl), sPassword, SID, True)   ; Encryption
MsgBox % sTextEncrypt
nSize := Text_AES(sTextDecrypt, &sTextEncrypt, nSize, sPassword, SID, False)   ; Decryption
MsgBox % sTextDecrypt

SID := 192   ; 192bit AES
nSize := Text_AES(sTextEncrypt, &sTextOriginl, StrLen(sTextOriginl), sPassword, SID, True)   ; Encryption
MsgBox % sTextEncrypt
nSize := Text_AES(sTextDecrypt, &sTextEncrypt, nSize, sPassword, SID, False)   ; Decryption
MsgBox % sTextDecrypt

SID := 256   ; 256bit AES
nSize := Text_AES(sTextEncrypt, &sTextOriginl, StrLen(sTextOriginl), sPassword, SID, True)   ; Encryption
MsgBox % sTextEncrypt
nSize := Text_AES(sTextDecrypt, &sTextEncrypt, nSize, sPassword, SID, False)   ; Decryption
MsgBox % sTextDecrypt
Return

Text_AES(ByRef sResult, pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   VarSetCapacity(sResult, bEncrypt ? nSize+16 : nSize)
   DllCall("RtlMoveMemory", "Uint", &sResult, "Uint", pData, "Uint", nSize)
   nSize := Crypt_AES(&sResult, nSize, sPassword, SID, bEncrypt)
   NumPut(0, sResult, nSize, "char"), VarSetCapacity(sResult,-1)
   Return   nSize
}


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 6th, 2010, 9:22 pm 
Offline

Joined: August 30th, 2010, 2:53 pm
Posts: 9
olfen wrote:
Sorry, I think I was wrong on CryptGenKey: It generates a session key\password and no IV.
CryptSetKeyParam can be passed a pointer to an IV, which we can choose\create ourselfes. IV and key are two seperate things, both needed when not using the cipher in ECB mode.
If not provided IV defaults to 0, as you mentioned before.

As you have written before, we can probably call CryptGenRandom to get our 16 byte IV and pass the pointer to the buffer to CryptSetKeyParam.


This is exactly correct. I can successfully set the IV with 16 bytes of randomly generated data, but the first block of text does not decrypt successfully.

Code:
nSize := Text_AES(sTextEncrypt, &sTextOriginl, StrLen(sTextOriginl), sPassword, SID, True)   ; Encryption
MsgBox % sTextEncrypt
nSize := Text_AES(sTextDecrypt, &sTextEncrypt, nSize, sPassword, SID, False)   ; Decryption
MsgBox % sTextDecrypt


Crypt_SetRandomIV(ByRef hProv, ByRef hKey)
{
  KP_IV := 1   
  dwBlockLen := 16 ; 128 bit (16 byte) block length for AES   
  VarSetCapacity(pbIV, dwBlockLen, 0) ; initialization vector
  DllCall("advapi32\CryptGenRandom", "UInt", hProv, "UInt", dwBlockLen, "Char", &pbIV) ; Generate random data into pbIV
  DllCall("advapi32\CryptSetKeyParam", "UInt", hKey, "UInt", KP_IV, "Char", &pbIV, "UInt", 0)
}


I then modified the Crypt_AES function and added:
Code:
Crypt_SetRandomIV(hProv, hKey)

inside of the If bEncrypt block. Anyone know why the decrypt is not functioning correctly?

I could modify my function to fetch the block size first if necessary, but I figured it wasn't necessary as AES 128/192/256 all use a 128 bit block size so I just hard coded it to 16 bytes.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 8th, 2010, 1:57 am 
Offline

Joined: August 30th, 2010, 2:53 pm
Posts: 9
Nevermind. It helps if you use the same randomly generated IV to decrypt, and not a new random IV. :oops:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: AHK_L Version
PostPosted: December 16th, 2010, 7:53 am 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
.


Last edited by shajul on December 20th, 2010, 12:58 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 16th, 2010, 11:51 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
shajul wrote:
Here's the code. No need for File.ahk also..
Good. BTW, I think you better make clear what builds it targets. I can see it doesn't support currently 64bit AHKL, however, are you gonna support ANSI build or not?

It's good to know that you used RawRead/RawWrite. OTOH, I think these parts can be improved, I may post the codes when times come.

Code:
DllCall("advapi32\CryptHashData", "Uint", hHash, "Uint", &sPassword, "Uint", StrLen(sPassword), "Uint", 0)
The only troublesome one is this one. Almost all crypto APIs treat the data as binary, so, they expect the length of the data in bytes, not in characters. So, with the UNICODE build, the code will actually use only the first half of the sPassword. It better be StrLen(sPassword) * 2 with the UNICODE build.

However, there still remains a problem if you're gonna support the ANSI build too. The encrypted file with the UNICODE build won't be decrypted with the ANSI build, and vice versa, even if using (apparently) the same password. So, need to decide on this.
1) Drop the support for the ANSI build.
2) Make the sPassword part compatible for both ANSI and UNICODE builds. There are various options here again.

Quote:
Also, check out the improvement in the native zip routine (removed the sleep, better checking if file passed is zipped)here..
Finally, that's nice.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 20th, 2010, 12:24 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
AHK_L version that is compatible with both Ansi and Unicode, so that any file encrypted with Unicode version should be decrypted with Ansi version and vice-versa.

Also, this should work with 64 bit builds also (untested), though i have not incorporated handling of large unsigned integers in x64 (i dont know if this is needed).

@Sean: Here's the code updated. Thanks for the pointers. Please review critically if something still sucks..

Code:
sFileOriginl   := A_ScriptFullPath
sPassword   := "AutoHotkey"

SID := 256   ; 128 for 128bit, 192 for 192bit AES
sFileEncrypt := A_ScriptDir . "\encrypt" . SID . ".bin"
sFileDecrypt := A_ScriptDir . "\decrypt" . SID . ".ahk"

StrPutVar(Password, sPassword, "UTF-8") ;Change encoding to be consistent in Ansi or Unicode builds

File_AES(sFileOriginl, sFileEncrypt, sPassword, SID, True)   ; Encryption
File_AES(sFileEncrypt, sFileDecrypt, sPassword, SID, False)   ; Decryption

File_AES(sFileFr, sFileTo, sPassword, SID = 256, bEncrypt = True)
{
   hFileFr := FileOpen(sFileFr,"r -r")
   if not hFileFr
      Return   "File not found!"
   nSize := hFileFr.Length
   VarSetCapacity(sData, nSize + (bEncrypt ? 16 : 0))
   hFileFr.Seek(0)
   hFileFr.RawRead(sData, nSize)
   hFileFr.Close()
   hFileTo := FileOpen(sFileTo,"w -r")
   if not hFileTo
      Return   "File not created/opened!"
   nSize := Crypt_AES(&sData, nSize, sPassword, SID, bEncrypt)
   hFileTo.RawWrite(sData, nSize)
   hFileTo.Close()
      Return   nSize
}

Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContext", "UPtr*", hProv, "UPtr", 0, "UPtr", 0, "UPtr", 24, "UPtr", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "UPtr", hProv, "UPtr", CALG_SHA1, "UPtr", 0, "UPtr", 0, "UPtr*", hHash)
   DllCall("advapi32\CryptHashData", "UPtr", hHash
   , "UPtr", &sPassword
   , "UPtr", StrLen(sPassword)*2, "UPtr", 0)
   DllCall("advapi32\CryptDeriveKey", "UPtr", hProv, "UPtr", CALG_AES_%SID%, "UPtr", hHash, "UPtr", SID<<16, "UPtr*", hKey)
   DllCall("advapi32\CryptDestroyHash", "UPtr", hHash)
   bEncrypt
   ? DllCall("advapi32\CryptEncrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0, "UPtr", pData, "UPtr*", nSize, "UPtr", nSize+16)
   : DllCall("advapi32\CryptDecrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0, "UPtr", pData, "UPtr*", nSize)
   DllCall("advapi32\CryptDestroyKey", "UPtr", hKey)
   DllCall("advapi32\CryptReleaseContext", "UPtr", hProv, "UPtr", 0)
   Return   nSize
}

StrPutVar(string, ByRef var, encoding)
{
    VarSetCapacity( var, StrPut(string, encoding) * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    return StrPut(string, &var, encoding)
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 20th, 2010, 2:12 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
shajul wrote:
Code:
StrPutVar(Password, sPassword, "UTF-8") ;Change encoding to be consistent in Ansi or Unicode builds
This part may not be what you expected. In fact, it's not safe for either ANSI or UNICODE AHK_L, even can crash both versions of AHK_L in some codepages. My preference was/is dropping the support for ANSI AHK_L as I personally think that the very ANSI AHK_L should be abandoned as soon as possible before it deepens the confusion of the users.

And, I can see you just replaced int with ptr. Fortunately there will be no problem with this very code, this can be problematic, especially with out parameters, for example, nSize in this code. Anyway, blindly replacing int with ptr is not a good practice IMO.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 20th, 2010, 5:03 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
Sean wrote:
And, I can see you just replaced int with ptr.


i did that because i thought it'll support 64 bit. Would it be better to use UInt64 after determining A_PtrSize?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 21st, 2010, 1:48 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
shajul wrote:
i did that because i thought it'll support 64 bit. Would it be better to use UInt64 after determining A_PtrSize?
No, using Ptr is a good thing, as a matter of fact that's the whole purpose of the birth of the Ptr type. What I was concerned was that you had also used it even with other types. For example, nSize parameter should remain as a UInt type in both 32bit/64bit AHK_L. Fortunately, this type mismatch mostly doesn't matter with in only parameters, however, can be problematic with (in-)out parameters.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 21st, 2010, 5:54 am 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
I am learning a bit by bit :) thanks a lot.

Finally, here is the code with Ansi support dropped and (i hope) x64 support retained. I have replaced both in-out parameters with UInt's again..

Code:
sFileOriginl   := A_ScriptFullPath
sPassword   := "AutoHotkey"

SID := 256   ; 128 for 128bit, 192 for 192bit AES
sFileEncrypt := A_ScriptDir . "\encrypt" . SID . ".bin"
sFileDecrypt := A_ScriptDir . "\decrypt" . SID . ".ahk"

File_AES(sFileOriginl, sFileEncrypt, sPassword, SID, True)   ; Encryption
File_AES(sFileEncrypt, sFileDecrypt, sPassword, SID, False)   ; Decryption

File_AES(sFileFr, sFileTo, sPassword, SID = 256, bEncrypt = True)
{
   hFileFr := FileOpen(sFileFr,"r -r")
   if not hFileFr
      Return   "File not found!"
   nSize := hFileFr.Length
   VarSetCapacity(sData, nSize + (bEncrypt ? 16 : 0))
   hFileFr.Seek(0)
   hFileFr.RawRead(sData, nSize)
   hFileFr.Close()
   hFileTo := FileOpen(sFileTo,"w -r")
   if not hFileTo
      Return   "File not created/opened!"
   nSize := Crypt_AES(&sData, nSize, sPassword, SID, bEncrypt)
   hFileTo.RawWrite(sData, nSize)
   hFileTo.Close()
      Return   nSize
}

Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContext", "UPtr*", hProv, "UPtr", 0, "UPtr", 0, "UPtr", 24, "UPtr", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "UPtr", hProv, "UPtr", CALG_SHA1, "UPtr", 0, "UPtr", 0, "UPtr*", hHash)
   DllCall("advapi32\CryptHashData", "UPtr", hHash
   , "UPtr", &sPassword
   , "UPtr", (A_IsUnicode ? StrLen(sPassword)*2 : StrLen(sPassword)), "UPtr", 0)
   DllCall("advapi32\CryptDeriveKey", "UPtr", hProv, "UPtr", CALG_AES_%SID%, "UPtr", hHash, "UPtr", SID<<16, "UPtr*", hKey)
   DllCall("advapi32\CryptDestroyHash", "UPtr", hHash)
   bEncrypt
   ? DllCall("advapi32\CryptEncrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize, "UPtr", nSize+16)
   : DllCall("advapi32\CryptDecrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize)
   DllCall("advapi32\CryptDestroyKey", "UPtr", hKey)
   DllCall("advapi32\CryptReleaseContext", "UPtr", hProv, "UPtr", 0)
   Return   nSize
}


This is the MSDN reference i googled..
Quote:
BOOL WINAPI CryptEncrypt(
__in HCRYPTKEY hKey,
__in HCRYPTHASH hHash,
__in BOOL Final,
__in DWORD dwFlags,
__inout BYTE *pbData,
__inout DWORD *pdwDataLen,
__in DWORD dwBufLen
);


In this reference, even pbData is a pointer. I dont understand why our DllCall should not be "UIntP" instead of "UInt" in your original code? But it still works, btw.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 16th, 2011, 7:27 am 
I'm having issues with encryption using the Crypt_AES() function with AHK Basic.

If I use the text to be encrypted/decrypted directly in the script, it works, however if I instead load the encrypted text from file, it stops working?

Why?

Code:
orginput := "this is a test"
orgpass = test

orgsize := StrLen(orginput)

encsize := Crypt_AES(&orginput, orgsize, orgpass, 256, 1)

MsgBox % encsize "`n`n" orginput

newersize := Crypt_AES(&orginput, encsize, orgpass, 256, 0)

StringLeft, orginput, orginput, % orgsize

MsgBox % orgsize "`n`n" orginput

; --- Now the same with the encrypted data saved into a file...

FileRead, encdata, encdata.dat

;encsize := Crypt_AES(&encdata, orgsize, orgpass, 256, 1)

;MsgBox % encsize "`n`n" encdata

newersize := Crypt_AES(&encdata, encsize, orgpass, 256, 0)

StringLeft, encdata, encdata, % orgsize

MsgBox % orgsize "`n`n" encdata

Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContextA", "UintP", hProv, "Uint", 0, "Uint", 0, "Uint", 24, "Uint", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "Uint", hProv, "Uint", CALG_SHA1, "Uint", 0, "Uint", 0, "UintP", hHash)
   DllCall("advapi32\CryptHashData", "Uint", hHash, "Uint", &sPassword, "Uint", StrLen(sPassword), "Uint", 0)
   DllCall("advapi32\CryptDeriveKey", "Uint", hProv, "Uint", CALG_AES_%SID%, "Uint", hHash, "Uint", SID<<16, "UintP", hKey)
   DllCall("advapi32\CryptDestroyHash", "Uint", hHash)
   If   bEncrypt
      DllCall("advapi32\CryptEncrypt", "Uint", hKey, "Uint", 0, "Uint", True, "Uint", 0, "Uint", pData, "UintP", nSize, "Uint", nSize+16)
   Else   DllCall("advapi32\CryptDecrypt", "Uint", hKey, "Uint", 0, "Uint", True, "Uint", 0, "Uint", pData, "UintP", nSize)
   DllCall("advapi32\CryptDestroyKey", "Uint", hKey)
   DllCall("advapi32\CryptReleaseContext", "Uint", hProv, "Uint", 0)
   Return   nSize
}



:?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 12th, 2011, 3:02 am 
Offline

Joined: March 10th, 2011, 7:17 pm
Posts: 374
is it possible to do RSA public key with this?


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2

All times are UTC [ DST ]


Who is online

Users browsing this forum: Exabot [Bot], Stigg and 9 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group