 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Tue May 20, 2008 4:08 am Post subject: |
|
|
After reading the post below, I tried to write this one. HTH.
http://www.autohotkey.com/forum/topic31420.html&sid=7338d160f7bf3e9194c9335275e974dd
| 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
}
|
|
|
| Back to top |
|
 |
manonstreet
Joined: 30 Aug 2010 Posts: 9
|
Posted: Mon Sep 06, 2010 8:22 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
manonstreet
Joined: 30 Aug 2010 Posts: 9
|
Posted: Wed Sep 08, 2010 12:57 am Post subject: |
|
|
Nevermind. It helps if you use the same randomly generated IV to decrypt, and not a new random IV.  |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Thu Dec 16, 2010 6:53 am Post subject: AHK_L Version |
|
|
.
Last edited by shajul on Mon Dec 20, 2010 11:58 am; edited 3 times in total |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2462
|
Posted: Thu Dec 16, 2010 10:51 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Mon Dec 20, 2010 11:24 am Post subject: |
|
|
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)
} |
|
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2462
|
Posted: Mon Dec 20, 2010 1:12 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Mon Dec 20, 2010 4:03 pm Post subject: |
|
|
| 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? |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2462
|
Posted: Tue Dec 21, 2010 12:48 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
shajul
Joined: 15 Sep 2006 Posts: 564
|
Posted: Tue Dec 21, 2010 4:54 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
n-l-i-d Guest
|
Posted: Wed Feb 16, 2011 6:27 am Post subject: |
|
|
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
}
|
 |
|
| Back to top |
|
 |
guest3456
Joined: 10 Mar 2011 Posts: 308
|
Posted: Sat Mar 12, 2011 2:02 am Post subject: |
|
|
| is it possible to do RSA public key with this? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|