[펌]Alternative to _StringEncrypt()
원문출처 : http://www.autoitscript.com/forum/topic/66005-alternative-to-stringencrypt/
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 php
What 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:
$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 ;==>rc4
These 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:0
Note 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/