2013. 7. 29. 12:31

원문출처 : http://www.autoitscript.com/forum/topic/66005-alternative-to-stringencrypt/

String.au3


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:

AutoIt          
$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/

:) 

Posted by 땡보