CE101 Posted August 11, 2010 Share Posted August 11, 2010 (edited) I need some advice on how to save an ecryption key from one session to the next. This may be a very stupid question based on my misunderstanding of encryption. If that's the case, my apologies. I have an Excel file in which there are some columns I would like to encrypt. I've already experimented with the relavent _Crypt functions and see how it works. In the following example I derive a key, ecrypt some data with that key and then decrypt it with the same key. expandcollapse popup#include <Debug.au3> _DebugSetup ("Debugger") #include <Crypt.au3> ; Syntax for Crypt functions ; _Crypt_DeriveKey($vPassword, $iALG_ID [, $iHash_ALG_ID = $CALG_MD5 ] ) ; _Crypt_EncryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; _Crypt_DecryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; Using $hKey1, encrypt some data and then decrypt it ; and verify that the decrypted data ($var4) is the same as the original data ($var1) $var1 = "ABCDEF" _Crypt_Startup() $hKey1 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) $var2 =_Crypt_EncryptData($var1, $hKey1, $CALG_RC4) _Crypt_DestroyKey($hKey1) _Crypt_Shutdown() $var3 = _Crypt_DecryptData($var2, $hKey1, $CALG_RC4) $var4 = BinaryToString($var3) ; Here I'm curious to see whether a second key will be the same as the first, if the same parameters were used for both _Crypt_Startup() $hKey2 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) _Crypt_DestroyKey($hKey2) _Crypt_Shutdown() _DebugOut("*** Encryption..." ) _DebugReportVar("$hKey1", $hKey1) _DebugReportVar("$hKey2", $hKey2) _DebugReportVar("Original................... $var1", $var1) _DebugReportVar("Encrypted.................. $var2", $var2) _DebugReportVar("Decrypted.................. $var3", $var3) _DebugReportVar("BinaryToString($var3)...... $var4", $var4) If $var1 <> $var4 Then _DebugOut("Test failed... $var1 <> $var4") EndIf If $hKey1 <> $hKey2 Then _DebugOut(" $hKey1 <> $hKey2 ... That's the way it should be") Else _DebugOut(" $hKey1 = $hKey2 ... This is a problem. Keys should be unique") EndIf ; At this point the debug results will look something like this ;~ @@ Debug(36) : {Ptr} -> $hKey1 = 0x008EF8A0 ;~ @@ Debug(50) : {Ptr} -> $hKey2 = 0x008EDEA0 ;~ @@ Debug(37) : {String:6} -> $var1 = "ABCDEF" ;~ @@ Debug(38) : {Binary:6} -> $var2 = 0x17985CC39A1C ;~ @@ Debug(39) : {Binary:6} -> $var3 = 0x414243444546 ;~ @@ Debug(40) : {String:6} -> $var4 = "ABCDEF" The question now is how do I save the key that was used to encrypt the data to be used another day to decrypt that same data. How do I save the key for future use. The variable $hKey1 is only a pointer (Ptr) to the location of the actual key. So by saving the pointer you are not saving the actual key. You are only saving the address at which the key is stored. However once the script finishes, the memory is released and the address has no more significance. In summary, how can I decrypt data that was encrypted in an earlier session. Any suggestions would be greatly appreciated. Sample code would be even better. Edited August 11, 2010 by CE101 Link to comment Share on other sites More sharing options...
saywell Posted August 11, 2010 Share Posted August 11, 2010 I know nothing of this, but isn't the key derived from the password? Assuming the same password causes the same key to be derived in subsequent cases, only the password needs saving. Easily tested... William Link to comment Share on other sites More sharing options...
omikron48 Posted August 11, 2010 Share Posted August 11, 2010 I don't think DeriveKey will generate the same key for the same password string on every call. Link to comment Share on other sites More sharing options...
CE101 Posted August 11, 2010 Author Share Posted August 11, 2010 To William(Saywell) and omikron48: Thank you for responding. Omikron48 is correct. DeriveKey will not generate the same key on every call, even though the same password has been used , as demonstrated in the following code. expandcollapse popup#include <Debug.au3> _DebugSetup ("Debugger") #include <Crypt.au3> ; Syntax for Crypt functions ; _Crypt_DeriveKey($vPassword, $iALG_ID [, $iHash_ALG_ID = $CALG_MD5 ] ) ; _Crypt_EncryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; _Crypt_DecryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; Using $hKey1, encrypt some data and then decrypt it ; and verify that the decrypted data ($var4) is the same as the original data ($var1) $var1 = "ABCDEF" _Crypt_Startup() $hKey1 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) $var2 =_Crypt_EncryptData($var1, $hKey1, $CALG_RC4) _Crypt_DestroyKey($hKey1) _Crypt_Shutdown() $var3 = _Crypt_DecryptData($var2, $hKey1, $CALG_RC4) $var4 = BinaryToString($var3) ; Generate a second key ($hKey2) using the same criteria as the first and with this new key decrypt the original data ; and verify that the decrypted data ($var6) is the same as the original data ($var1) _Crypt_Startup() $hKey2 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) _Crypt_DestroyKey($hKey2) _Crypt_Shutdown() $var5 = _Crypt_DecryptData($var2, $hKey2, $CALG_RC4) $var6 = BinaryToString($var5) _DebugOut("*** Encryption..." ) _DebugReportVar("$hKey1", $hKey1) _DebugReportVar("$hKey2", $hKey2) _DebugReportVar("Original................... $var1", $var1) _DebugReportVar("Encrypted.................. $var2", $var2) _DebugReportVar("Decrypted with $hKey1...... $var3", $var3) _DebugReportVar("BinaryToString($var3)...... $var4", $var4) _DebugReportVar("Decrypted with $hKey2...... $var5", $var5) _DebugReportVar("BinaryToString($var5)...... $var6", $var6) If $var1 <> $var4 Then _DebugOut("Test failed... $var1 <> $var4") EndIf If $var1 <> $var6 Then _DebugOut("Test failed... $var1 <> $var6") EndIf If $hKey1 <> $hKey2 Then _DebugOut(" $hKey1 <> $hKey2 ... That's the way it should be") Else _DebugOut(" $hKey1 = $hKey2 ... This is a problem. Keys should be unique") EndIf ; At this point the debug results will look something like this ;~ *** Encryption... ;~ @@ Debug(42) : {Ptr} -> $hKey1 = 0x008EF8A0 ;~ @@ Debug(43) : {Ptr} -> $hKey2 = 0x008EDEA0 ;~ @@ Debug(44) : {String:6} -> Original................... $var1 = "ABCDEF" ;~ @@ Debug(45) : {Binary:6} -> Encrypted.................. $var2 = 0x17985CC39A1C ;~ @@ Debug(46) : {Binary:6} -> Decrypted with $hKey1...... $var3 = 0x414243444546 ;~ @@ Debug(47) : {String:6} -> BinaryToString($var3)...... $var4 = "ABCDEF" ;~ @@ Debug(48) : {Binary:6} -> Decrypted with $hKey2...... $var5 = 0x9AF4ED071F96 ;~ @@ Debug(49) : {String:6} -> BinaryToString($var5)...... $var6 = "šôà –" ;~ Test failed... $var1 <> $var6 Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted August 13, 2010 Share Posted August 13, 2010 Just from a quick glance at MSDN (linked to from the AutoIt Help File), the session key is stored as a handle to another area. To quote the page regarding these keys:The HCRYPTKEY data type is used to represent handles to cryptographic keys. These handles are used to indicate to the CSP module which key is being used in a specific operation. The CSP module does not enable direct access to the key values. Instead, the user performs functions by using the key value through the key handle.Storing the handles obviously won't work then. However, a page back shows this: The CryptDeriveKey function generates cryptographic session keys derived from a base data value. This function guarantees that when the same cryptographic service provider (CSP) and algorithms are used, the keys generated from the same base data are identical. The base data can be a password or any other user data.The emphasis was added by me, but as you can see, it should just work the same, when generated the same. I haven't looked at the source to Crypt.au3 yet, to see how it's calling the dll, but I would start there and see what other options you need. Link to comment Share on other sites More sharing options...
ProgAndy Posted August 13, 2010 Share Posted August 13, 2010 The problems occur since you do not use the functions correctly. If you create your own $hKey, you have to use $CALC_USERKEY in the call to EncryptData. Otherwise, _Crypt_EnCryptData creates the $hKey itself (using the binary representation of the handle you specified). This results in different keys since the "password" ist different each time. Correct usage would be: expandcollapse popup#include <Debug.au3> _DebugSetup ("Debugger") #include <Crypt.au3> ; Syntax for Crypt functions ; _Crypt_DeriveKey($vPassword, $iALG_ID [, $iHash_ALG_ID = $CALG_MD5 ] ) ; _Crypt_EncryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; _Crypt_DecryptData($vData, $vCryptKey, $iALG_ID[, $fFinal = True]) ; Using $hKey1, encrypt some data and then decrypt it ; and verify that the decrypted data ($var4) is the same as the original data ($var1) $sString = "ABCDEF" $bBinaryString = StringToBinary($sString) _Crypt_Startup() $hKey1 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) $bBinaryEncrypted = _Crypt_EncryptData($bBinaryString, $hKey1, $CALG_USERKEY) _Crypt_DestroyKey($hKey1) _Crypt_Shutdown() ; Generate a second key ($hKey2) using the same criteria as the first and with this new key decrypt the original data ; and verify that the decrypted data ($var6) is the same as the original data ($var1) _Crypt_Startup() $hKey2 = _Crypt_DeriveKey("SomePassword", $CALG_RC4) $bBinaryDecrypted = _Crypt_DecryptData($bBinaryEncrypted, $hKey2, $CALG_USERKEY) _Crypt_DestroyKey($hKey2) _Crypt_Shutdown() $sStringDecrypted = BinaryToString($bBinaryDecrypted) _DebugOut("*** Encryption..." ) _DebugReportVar("Original................... $sString ", $sString) _DebugReportVar("Binary..................... $bBinaryString ", $bBinaryString) _DebugReportVar("Encrypted.................. $bBinaryEncrypted", $bBinaryEncrypted) _DebugReportVar("Decrypted with $hKey2...... $bBinaryDecrypted", $bBinaryDecrypted) _DebugReportVar("BinaryToString($var5)...... $sStringDecrypted", $sStringDecrypted) Or #include <Debug.au3> _DebugSetup ("Debugger") #include <Crypt.au3> ; Using $hKey1, encrypt some data and then decrypt it ; and verify that the decrypted data ($var4) is the same as the original data ($var1) $sString = "ABCDEF" $bBinaryString = StringToBinary($sString) $bBinaryEncrypted = _Crypt_EncryptData($bBinaryString, "SomePassword", $CALG_RC4) ; Generate a second key ($hKey2) using the same criteria as the first and with this new key decrypt the original data ; and verify that the decrypted data ($var6) is the same as the original data ($var1) $bBinaryDecrypted = _Crypt_DecryptData($bBinaryEncrypted, "SomePassword", $CALG_RC4) $sStringDecrypted = BinaryToString($bBinaryDecrypted) _DebugOut("*** Encryption..." ) _DebugReportVar("Original................... $sString ", $sString) _DebugReportVar("Binary..................... $bBinaryString ", $bBinaryString) _DebugReportVar("Encrypted.................. $bBinaryEncrypted", $bBinaryEncrypted) _DebugReportVar("Decrypted with $hKey2...... $bBinaryDecrypted", $bBinaryDecrypted) _DebugReportVar("BinaryToString($var5)...... $sStringDecrypted", $sStringDecrypted) Or ; Using $hKey1, encrypt some data and then decrypt it ; and verify that the decrypted data ($var4) is the same as the original data ($var1) $sString = "ABCDEF" $bBinaryString = StringToBinary($sString) _Crypt_Startup() $hKey1 =_Crypt_DeriveKey("SomePassword", $CALG_RC4) $bBinaryEncrypted = _Crypt_EncryptData($bBinaryString, $hKey1, $CALG_USERKEY) _Crypt_DestroyKey($hKey1) _Crypt_Shutdown() ; Generate a second key ($hKey2) using the same criteria as the first and with this new key decrypt the original data ; and verify that the decrypted data ($var6) is the same as the original data ($var1) $bBinaryDecrypted = _Crypt_DecryptData($bBinaryEncrypted, "SomePassword", $CALG_RC4) $sStringDecrypted = BinaryToString($bBinaryDecrypted) _DebugOut("*** Encryption..." ) _DebugReportVar("Original................... $sString ", $sString) _DebugReportVar("Binary..................... $bBinaryString ", $bBinaryString) _DebugReportVar("Encrypted.................. $bBinaryEncrypted", $bBinaryEncrypted) _DebugReportVar("Decrypted with $hKey2...... $bBinaryDecrypted", $bBinaryDecrypted) _DebugReportVar("BinaryToString($var5)...... $sStringDecrypted", $sStringDecrypted) or ... There are many different ways. To speed up the calls, you can call _Crypt_Startup() once at the beginning of the script and on exit (e.g. OnAutoItExitRegister) call _Crypt_Shutdown(). *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
CE101 Posted August 16, 2010 Author Share Posted August 16, 2010 To ProgAndy: Thank you for the three examples! One would have been sufficient. But three is fantastic! Problem solved. To SkinnyWhiteGuy: Thank you for the MSDN information. I haven't checked that DLL stuff because it seems I already have a solution. However thanks to you I now know where to look in the future. You guys are great! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now