PsaltyDS Posted March 8, 2008 Share Posted March 8, 2008 (edited) This function came out of my trying to understand a supposed problem with _StringEncrypt(). Only one user reported that problem, and it was never duplicated by anyone else, so it very well may not be a bug, and this is not an attempt to "fix" _StringEncrypt().The only thing I wanted to achieve was a version of _StringEncrypt() that would output a "standard" result for RC4 encryption, that would match RC4 implementations on web sites and in other languages. The encryption side of that was completely solved by SkinnyWhiteGuy in the topic: equal encrypt function autoit and phpWhat I did here was match the string-based nature of _StringEncrypt(), vice the binary nature of RC4(), with the multi-pass encryption functionality provided by the $i_EncryptLevel parameter. The result is __StringEncrypt(), with the double-underbar in the name.Here is the function, within a basic test script:expandcollapse popup$sString = "This is a text string" ConsoleWrite("Debug: $sString = " & $sString & @LF) $sKey = "Key phrase" ConsoleWrite("Debug: $sKey = " & $sKey & @LF) For $z = 1 To 4 ConsoleWrite("Debug: Encryption level = " & $z & @LF) $sEncrypted = __StringEncrypt(1, $sString, $sKey, $z) ConsoleWrite("Debug: $sEncrypted = " & $sEncrypted & @LF) $sDecrypted = __StringEncrypt(0, $sEncrypted, $sKey, $z) ConsoleWrite("Debug: $sDecrypted = " & $sDecrypted & @LF) Next ;=============================================================================== ; ; Function Name: __StringEncrypt() ; Description: RC4 Based string encryption/decryption ; Parameter(s): $i_Encrypt - 1 to encrypt, 0 to decrypt ; $s_EncryptText - string to encrypt ; $s_EncryptPassword - string to use as an encryption password ; $i_EncryptLevel - integer to use as number of times to encrypt string ; Requirement(s): None ; Return Value(s): On Success - Returns the encrypted string ; On Failure - Returns a blank string and sets @error = 1 ; Author(s): (Original _StringEncrypt) Wes Wolfe-Wolvereness <Weswolf at aol dot com> ; (Modified __StringEncrypt) PsaltyDS at www.autoitscript.com/forum ; (RC4 function) SkinnyWhiteGuy at www.autoitscript.com/forum ;=============================================================================== ; 1.0.0.0 | 03/08/08 | First version posted to Example Scripts Forum ;=============================================================================== Func __StringEncrypt($i_Encrypt, $s_EncryptText, $s_EncryptPassword, $i_EncryptLevel = 1) Local $RET, $sRET = "", $iBinLen, $iHexWords ; Sanity check of parameters If $i_Encrypt <> 0 And $i_Encrypt <> 1 Then SetError(1) Return '' ElseIf $s_EncryptText = '' Or $s_EncryptPassword = '' Then SetError(1) Return '' EndIf If Number($i_EncryptLevel) <= 0 Or Int($i_EncryptLevel) <> $i_EncryptLevel Then $i_EncryptLevel = 1 ; Encrypt/Decrypt If $i_Encrypt Then ; Encrypt selected $RET = $s_EncryptText For $n = 1 To $i_EncryptLevel If $n > 1 Then $RET = Binary(Random(0, 2 ^ 31 - 1, 1)) & $RET & Binary(Random(0, 2 ^ 31 - 1, 1)) ; prepend/append random 32bits $RET = rc4($s_EncryptPassword, $RET) ; returns binary Next ; Convert to hex string $iBinLen = BinaryLen($RET) $iHexWords = Int($iBinLen / 4) If Mod($iBinLen, 4) Then $iHexWords += 1 For $n = 1 To $iHexWords $sRET &= Hex(BinaryMid($RET, 1 + (4 * ($n - 1)), 4)) Next $RET = $sRET Else ; Decrypt selected ; Convert input string to primary binary $RET = Binary("0x" & $s_EncryptText) ; Convert string to binary ; Additional passes, if required For $n = 1 To $i_EncryptLevel If $n > 1 Then $iBinLen = BinaryLen($RET) $RET = BinaryMid($RET, 5, $iBinLen - 8) ; strip random 32bits from both ends EndIf $RET = rc4($s_EncryptPassword, $RET) Next $RET = BinaryToString($RET) EndIf ; Return result Return $RET EndFunc ;==>__StringEncrypt ; ------------------------------------------------------- ; Function: rc4 ; Purpose: An encryption/decryption RC4 implementation in AutoIt ; Syntax: rc4($key, $value) ; Where: $key = encrypt/decrypt key ; $value = value to be encrypted/decrypted ; On success returns encrypted/decrypted version of $value ; Author: SkinnyWhiteGuy on the AutoIt forums at www.autoitscript.com/forum ; Notes: The same function encrypts and decrypts $value. ; ------------------------------------------------------- Func rc4($key, $value) Local $S[256], $i, $j, $c, $t, $x, $y, $output Local $keyLength = BinaryLen($key), $valLength = BinaryLen($value) For $i = 0 To 255 $S[$i] = $i Next For $i = 0 To 255 $j = Mod($j + $S[$i] + Dec(StringTrimLeft(BinaryMid($key, Mod($i, $keyLength) + 1, 1), 2)), 256) $t = $S[$i] $S[$i] = $S[$j] $S[$j] = $t Next For $i = 1 To $valLength $x = Mod($x + 1, 256) $y = Mod($S[$x] + $y, 256) $t = $S[$x] $S[$x] = $S[$y] $S[$y] = $t $j = Mod($S[$x] + $S[$y], 256) $c = BitXOR(Dec(StringTrimLeft(BinaryMid($value, $i, 1), 2)), $S[$j]) $output = Binary($output) & Binary('0x' & Hex($c, 2)) Next Return $output EndFunc ;==>rc4These are the results of two consecutive runs in SciTE:>Running:(3.2.10.0):C:\Program Files\AutoIt3\autoit3.exe "C:\Program Files\AutoIt3\Scripts\Test_1.au3" Debug: $sString = This is a text string Debug: $sKey = Key phrase Debug: Encryption level = 1 Debug: $sEncrypted = 13BFA0643B2D2B75A2FA41A98B0B363748DB0EC8C5 Debug: $sDecrypted = This is a text string Debug: Encryption level = 2 Debug: $sEncrypted = FC92DD7408FBF831F8F71EB9518557EDB7A25191EAB226AEB9CF3776E3 Debug: $sDecrypted = This is a text string Debug: Encryption level = 3 Debug: $sEncrypted = 553996021B3DCE57CB21CDFD0B8808FD6D2C304B15CB79F796C76BA4680B031A03B2175035 Debug: $sDecrypted = This is a text string Debug: Encryption level = 4 Debug: $sEncrypted = BCB5DD4D8F19ED1D98BF8285385EDBB937216F5BCF45182D69BE34FD472FE0D6CE404C747C269F35C8F27D790C Debug: $sDecrypted = This is a text string +>13:06:59 AutoIT3.exe ended.rc:0>Running:(3.2.10.0):C:\Program Files\AutoIt3\autoit3.exe "C:\Program Files\AutoIt3\Scripts\Test_1.au3" Debug: $sString = This is a text string Debug: $sKey = Key phrase Debug: Encryption level = 1 Debug: $sEncrypted = 13BFA0643B2D2B75A2FA41A98B0B363748DB0EC8C5 Debug: $sDecrypted = This is a text string Debug: Encryption level = 2 Debug: $sEncrypted = 3F83796908FBF831F8F71EB9518557EDB7A25191EAB226AEB9261552D2 Debug: $sDecrypted = This is a text string Debug: Encryption level = 3 Debug: $sEncrypted = 4FEEF71FB98E811CCB21CDFD0B8808FD6D2C304B15CB79F796C76BA468D39E1676FC9FAA1A Debug: $sDecrypted = This is a text string Debug: Encryption level = 4 Debug: $sEncrypted = 600821594D0853343717D6DA385EDBB937216F5BCF45182D69BE34FD472FE0D6CE1CC2B3258B0833861A82BA52 Debug: $sDecrypted = This is a text string +>13:08:34 AutoIT3.exe ended.rc:0Note that the encrypted string is the same between the two runs where $i_EncryptLevel = 1, but is different where $i_EncryptLevel > 1. It is useful in some contexts to get different results that can still be decrypted with same key to the same value.As long as $i_EncryptLevel = 1, this function should be directly compatible with string-based RC4 implementations elsewhere (on web sites or in applications). For example, you'll get the same result if you put the string "This is a text string" and the key "Key phrase" into this web site: http://www.4guysfromrolla.com/ Edited September 30, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
ptrex Posted March 9, 2008 Share Posted March 9, 2008 @PsaltyDS Very nice !! regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 10, 2008 Author Share Posted March 10, 2008 (edited) @PsaltyDS Very nice !! regards ptrex Thanks. I'd really love to know if anyone has tested it against other RC4 implementations, like PHP or Java on a web site other than my example. Compatibility with other implementations was the original purpose. P.S. Tested against one more site (data has to be entered in URL): www.colcyber.com/macro Result is:Original Data : This is a text string Encrypted Data (using Hex Key) : cb628ff60e96ae5f0409598d67e2c1f72a3f24aeac Decrypted Data (using Hex Key) : This is a text string Encrypted Data (using Key as is) : 13bfa0643b2d2b75a2fa41a98b0b363748db0ec8c5 Decrypted Data (using Key as is) : This is a text string I guess "using Hex Key" means the key was converted somehow, making the result different. With "using Key as is" the result matches my function (with $iEncryptLevel = 1). Edited March 10, 2008 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
kurey Posted June 8, 2008 Share Posted June 8, 2008 this funtion may have something wrong when run with the unicode version.i use the __StringEncrypt funtion to Encrypt some NON ascii characterS like :服务器 <------Chinese (means "server")わたし <------Japanese(means "I")and run with the unicode version(3.2.10.0) on Windos xp Simplified Chinese verion ,and the result is :Encrypt:dcrypt :expandcollapse popup#include <guiconstants.au3> ;#include <string.au3> ; GUI and String stuff $WinMain = GuiCreate('Encryption tool', 400, 400) ; Creates window $EditText = GuiCtrlCreateEdit('',5,5,380,350) ; Creates main edit $InputPass = GuiCtrlCreateInput('',5,360,100,20, 0x21) ; Creates the password box with blured/centered input $InputLevel = GuiCtrlCreateInput(1, 110, 360, 50, 20, 0x2001) $UpDownLevel = GUICtrlSetLimit(GuiCtrlCreateUpDown($inputlevel),10,1) ; These two make the level input with the Up|Down ability $EncryptButton = GuiCtrlCreateButton('Encrypt', 170, 360, 105, 35) ; Encryption button $DecryptButton = GuiCtrlCreateButton('Decrypt', 285, 360, 105, 35) ; Decryption button GUICtrlCreateLabel('Password', 5, 385) GuiCtrlCreateLabel('Level',110,385) ; Simple text labels so you know what is what GuiSetState() ; Shows window Do $Msg = GuiGetMsg() If $msg = $EncryptButton Then GuiSetState(@SW_DISABLE,$WinMain); Stops you from changing anything $string = GuiCtrlRead($EditText); Saves the editbox for later GUICtrlSetData($EditText,'Please wait while the text is Encrypted/Decrypted.'); Friendly message GuiCtrlSetData($EditText,__StringEncrypt(1,$string,GuiCtrlRead($InputPass),GuiCtrlRead($InputLevel))) ; Calls the encryption. Sets the data of editbox with the encrypted string ; The encryption starts with 1/0 to tell it to encrypt/decrypt ; The encryption then has the string that we saved for later from edit box ; It then reads the password box & Reads the level box GuiSetState(@SW_ENABLE,$WinMain); This turns the window back on EndIf If $msg = $DecryptButton Then GuiSetState(@SW_DISABLE,$WinMain); Stops you from changing anything $string = GuiCtrlRead($EditText); Saves the editbox for later GUICtrlSetData($EditText,'Please wait while the text is Encrypted/Decrypted.'); Friendly message GuiCtrlSetData($EditText,__StringEncrypt(0,$string,GuiCtrlRead($InputPass),GuiCtrlRead($InputLevel))) ; Calls the encryption. Sets the data of editbox with the encrypted string ; The encryption starts with 1/0 to tell it to encrypt/decrypt ; The encryption then has the string that we saved for later from edit box ; It then reads the password box & Reads the level box GuiSetState(@SW_ENABLE,$WinMain); This turns the window back on EndIf Until $msg = $GUI_EVENT_CLOSE; Continue loop untill window is closed ;=============================================================================== ; ; Function Name: ___StringEncrypt() ; Description: RC4 Based string encryption/decryption ; Parameter(s): $i_Encrypt - 1 to encrypt, 0 to decrypt ; $s_EncryptText - string to encrypt ; $s_EncryptPassword - string to use as an encryption password ; $i_EncryptLevel - integer to use as number of times to encrypt string ; Requirement(s): None ; Return Value(s): On Success - Returns the string encrypted (blank) times with (blank) password ; On Failure - Returns a blank string and sets @error = 1 ; Author(s): (Original __StringEncrypt) Wes Wolfe-Wolvereness <Weswolf at aol dot com> ; (Modified ___StringEncrypt) PsaltyDS at www.autoitscript.com/forum ; (RC4 function) SkinnyWhiteGuy at www.autoitscript.com/forum ;=============================================================================== ; 1.0.0.0 | 03/08/08 | First version posted to Example Scripts Forum ;=============================================================================== Func __StringEncrypt($i_Encrypt, $s_EncryptText, $s_EncryptPassword, $i_EncryptLevel = 1) Local $RET, $sRET = "", $iBinLen, $iHexWords ; Sanity check of parameters If $i_Encrypt <> 0 And $i_Encrypt <> 1 Then SetError(1) Return '' ElseIf $s_EncryptText = '' Or $s_EncryptPassword = '' Then SetError(1) Return '' EndIf If Number($i_EncryptLevel) <= 0 Or Int($i_EncryptLevel) <> $i_EncryptLevel Then $i_EncryptLevel = 1 ; Encrypt/Decrypt If $i_Encrypt Then ; Encrypt selected $RET = $s_EncryptText For $n = 1 To $i_EncryptLevel If $n > 1 Then $RET = Binary(Random(0, 2 ^ 31 - 1, 1)) & $RET & Binary(Random(0, 2 ^ 31 - 1, 1)); prepend/append random 32bits $RET = rc4($s_EncryptPassword, $RET); returns binary Next ; Convert to hex string $iBinLen = BinaryLen($RET) $iHexWords = Int($iBinLen / 4) If Mod($iBinLen, 4) Then $iHexWords += 1 For $n = 1 To $iHexWords $sRET &= Hex(BinaryMid($RET, 1 + (4 * ($n - 1)), 4)) Next $RET = $sRET Else ; Decrypt selected ; Convert input string to primary binary $RET = Binary("0x" & $s_EncryptText); Convert string to binary ; Additional passes, if required For $n = 1 To $i_EncryptLevel If $n > 1 Then $iBinLen = BinaryLen($RET) $RET = BinaryMid($RET, 5, $iBinLen - 8); strip random 32bits from both ends EndIf $RET = rc4($s_EncryptPassword, $RET) Next $RET = BinaryToString($RET) EndIf ; Return result Return $RET EndFunc ;==>___StringEncrypt ; ------------------------------------------------------- ; Function: rc4 ; Purpose: An encryption/decryption RC4 implementation in AutoIt ; Syntax: rc4($key, $value) ; Where: $key = encrypt/decrypt key ; $value = value to be encrypted/decrypted ; On success returns encrypted/decrypted version of $value ; Author: SkinnyWhiteGuy on the AutoIt forums at www.autoitscript.com/forum ; Notes: The same function encrypts and decrypts $value. ; ------------------------------------------------------- Func rc4($key, $value) Local $S[256], $i, $j, $c, $t, $x, $y, $output Local $keyLength = BinaryLen($key), $valLength = BinaryLen($value) For $i = 0 To 255 $S[$i] = $i Next For $i = 0 To 255 $j = Mod($j + $S[$i] + Dec(StringTrimLeft(BinaryMid($key, Mod($i, $keyLength) + 1, 1), 2)), 256) $t = $S[$i] $S[$i] = $S[$j] $S[$j] = $t Next For $i = 1 To $valLength $x = Mod($x + 1, 256) $y = Mod($S[$x] + $y, 256) $t = $S[$x] $S[$x] = $S[$y] $S[$y] = $t $j = Mod($S[$x] + $S[$y], 256) $c = BitXOR(Dec(StringTrimLeft(BinaryMid($value, $i, 1), 2)), $S[$j]) $output = Binary($output) & Binary('0x' & Hex($c, 2)) Next Return $output EndFunc ;==>rc4 Link to comment Share on other sites More sharing options...
Andreik Posted June 8, 2008 Share Posted June 8, 2008 Nice work PsaltyDS! I like RC4 algorithm. It's very easy to use. Link to comment Share on other sites More sharing options...
WeMartiansAreFriendly Posted June 8, 2008 Share Posted June 8, 2008 I love the simplicity of the encryption algorithm. Good work. Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet() Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 30, 2008 Author Share Posted June 30, 2008 this funtion may have something wrong when run with the unicode version. i use the __StringEncrypt funtion to Encrypt some NON ascii characterS like : 服务器 <------Chinese (means "server") わたし <------Japanese(means "I") and run with the unicode version(3.2.10.0) on Windos xp Simplified Chinese verion ,and the result is : Encrypt: dcrypt : Hmm... seems the problem is that BinaryToString() requires the coder to identify what the source encoding. The last thing __StringEncrypt() does when decrypting is BinaryToString(). Try modifying your copy with the appropriate flag to see if that gets it: Func __StringEncrypt($i_Encrypt, $s_EncryptText, $s_EncryptPassword, $i_EncryptLevel = 1) Local $RET, $sRET = "", $iBinLen, $iHexWords ; ...clip $RET = BinaryToString($RET, 1); <============= Change encoding type here EndIf ; Return result Return $RET EndFunc ;==>__StringEncrypt From the help file: Parameters expression = An expression to convert into a string. flag [optional] = Changes how the binary data is converted: flag = 1 (default), binary data is taken to be ANSI flag = 2, binary data is taken to be UTF16 Little Endian flag = 3, binary data is taken to be UTF16 Big Endian flag = 4, binary data is taken to be UTF8UTF16 Little Endian = 2 seems most likely. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Ting Posted June 30, 2008 Share Posted June 30, 2008 (edited) Hmm... seems the problem is that BinaryToString() requires the coder to identify what the source encoding. The last thing __StringEncrypt() does when decrypting is BinaryToString(). Try modifying your copy with the appropriate flag to see if that gets it: Func __StringEncrypt($i_Encrypt, $s_EncryptText, $s_EncryptPassword, $i_EncryptLevel = 1) Local $RET, $sRET = "", $iBinLen, $iHexWords ; ...clip $RET = BinaryToString($RET, 1); <============= Change encoding type here EndIf ; Return result Return $RET EndFunc;==>__StringEncrypt From the help file: UTF16 Little Endian = 2 seems most likely. Tried all flags. None of them works for Asian characters on my PC. Should the stringtobinary function be called somewhere also in the script with the correct encoding? >>>> Ha, my guess was correct. We need the stringtobinary function. The encryption/decryption of unicode characters (e.g. Asian lang. ) is perfectly solved and tested here: http://www.autoitscript.com/forum/index.ph...mp;#entry545002 Edited July 2, 2008 by Ting 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