Search the Community
Showing results for tags 'arcfour'.
-
This is my implementation of CipherSaber-2 ( http://ciphersaber.gurus.org/ ). CipherSaber is a version of RC4 that adds a 10 byte random IV to each piece of encoded data. CipherSaber-2 augments this with a configurable number of key setup rounds ( http://ciphersaber.gurus.org/faq.html#cs2 ). I decided to do the actual encryption / decryption in machine code so it is fast enough to be used on moderately sized files. The key setup is still done in AutoIt. I prefer this routine to AutoIt's _StringEncrypt because the output is the same size as the input, regardless of key rounds or encryption rounds. Note: If you visit the site to learn more or run the official test cases, a bunch of the links incorrectly point to a .com domain. Just change those to .org and they will work properly. #include-once #include <Memory.au3> OnAutoItExitRegister("__CS_Cleanup") Global $__g_CS_pCode = 0 ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CipherSaber ; Description ...: Encrypt / decrypt a chunk of binary data. ; Syntax ........: _CipherSaber( $bData, $sKey [, $iKeyRounds = 20 [, $doEncrypt = True ]] ) ; Parameters ....: $bData - Chunk of binary data. ; $sKey - User key, string <= 246 characters, will be truncated if too long. ; $iKeyRounds - [optional] Number of rounds during key setup. Default is 20. ; $doEncrypt - [optional] Whether to encrypt or decrypt. Default is True. ; Return values .: The encrypted / decrypted binary data. ; Author ........: Erik Pilsits ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: http://ciphersaber.gurus.org/ ; Example .......: No ; =============================================================================================================================== Func _CipherSaber($bData, $sKey, $iKeyRounds = 20, $doEncrypt = True) Local $IV = Default If Not $doEncrypt Then $IV = BinaryMid($bData, 1, 10) ; ; RC4 has max key length of 256 bytes ; user key has max length of 246 bytes to allow for 10 bytes of random IV Local $state = __CS_KeySetup(StringLeft($sKey, 246), $IV, $iKeyRounds) Local $sOut = Binary("") If $doEncrypt Then $sOut = $IV Else $bData = BinaryMid($bData, 11) EndIf ; Return $sOut & __CS_Cipher($bData, $state) EndFunc ;==>_CipherSaber ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CipherSaber_File ; Description ...: Encrypt / decrypt a file. ; Syntax ........: _CipherSaber_File( $fileIn, $fileOut, $sKey [, $iKeyRounds = 20 [, $doEncrypt = True ]] ) ; Parameters ....: $fileIn - Path to the input file. ; $fileOut - Path to the output file. ; $sKey - User key, string <= 246 characters, will be truncated if too long. ; $iKeyRounds - [optional] Number of rounds during key setup. Default is 20. ; $doEncrypt - [optional] Whether to encrypt or decrypt. Default is True. ; Return values .: Success - 1 ; Failure - 0 and sets @error ; | 1 - Error opening input file for readin ; | 2 - Error opening output file for writing ; Author ........: Erik Pilsits ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _CipherSaber_File($fileIn, $fileOut, $sKey, $iKeyRounds = 20, $doEncrypt = True) Local $hIn = FileOpen($fileIn, 16) If $hIn = -1 Then Return SetError(1, 0, 0) Local $hOut = FileOpen($fileOut, 2+8+16) If $hOut = -1 Then FileClose($hIn) Return SetError(2, 0, 0) EndIf ; Local $IV = Default If Not $doEncrypt Then $IV = FileRead($hIn, 10) ; Local $state = __CS_KeySetup(StringLeft($sKey, 246), $IV, $iKeyRounds) If $doEncrypt Then FileWrite($hOut, $IV) ; Local $bData While 1 $bData = FileRead($hIn, 1024^2*2) If @error Then ExitLoop FileWrite($hOut, __CS_Cipher($bData, $state)) WEnd ; FileClose($hIn) FileClose($hOut) ; Return 1 EndFunc ;==>_CipherSaber_File #region INTERNAL FUNCTIONS Func __CS_KeySetup($sKey, ByRef $IV, $iKeyRounds) Local $key = StringToBinary($sKey) Local $i, $j, $n ; If $IV = Default Then ; encrypt ; create 10 bytes random data for IV $IV = "" For $i = 1 To 10 $IV &= Hex(Random(0, 255, 1), 2) Next $IV = Binary("0x" & $IV) EndIf $key &= $IV ; ; key setup ; use struct for key+IV because they are faster than BinaryMid Local $state[256], $keylen = BinaryLen($key) Local $tKey = DllStructCreate("byte[" & $keylen & "]") DllStructSetData($tKey, 1, $key) ; For $i = 0 To 255 $state[$i] = $i Next ; $j = 0 For $k = 1 To $iKeyRounds For $i = 0 To 255 $j = Mod($j + $state[$i] + DllStructGetData($tKey, 1, Mod($i, $keylen) + 1), 256) $n = $state[$i] $state[$i] = $state[$j] $state[$j] = $n Next Next ; create state struct from array Local $tState = DllStructCreate("byte[256]") For $i = 0 To 255 DllStructSetData($tState, 1, $state[$i], $i+1) Next Return $tState EndFunc ;==>__CS_KeySetup Func __CS_Cipher(Const ByRef $bData, ByRef $tState) ; initialize machine code If Not $__g_CS_pCode Then Local $bCode If @AutoItX64 Then $bCode = Binary("0x5557565385D27E508D42FF4531C931ED488D7401018D55010FB6EA4863C54C01C00FB618440FB6D34501D14181E1FF0000004D63D94D01C3410FB613881041881B440210450FB6D2430FB6041030014883C1014839F175BD5B5E5F5DC3") Else $bCode = Binary("0x5557565383EC0C8B5424248B4C242885D27E598B44242031DB31ED891C2401C2895424088D55010FB6EA8D14290FB61A0FB6F3885C24078B1C2401F381E3FF00000089DF01CF891C240FB61F881A0FB65C2407881F0FB61201F20FB6F20FB61431301083C0013B44240875B883C40C5B5E5F5DC20C00") EndIf $__g_CS_pCode = _MemVirtualAlloc(0, BinaryLen($bCode), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) DllStructSetData(DllStructCreate("byte[" & BinaryLen($bCode) & "]", $__g_CS_pCode), 1, $bCode) EndIf ; set data to struct Local $i = 0, $j = 0, $n, $len = BinaryLen($bData) Local $tData = DllStructCreate("byte[" & $len & "]") DllStructSetData($tData, 1, $bData) ; call cipher DllCallAddress("none", $__g_CS_pCode, "struct*", $tData, "int", $len, "struct*", $tState) ; ;~ For $k = 1 To $len ;~ $i = Mod($i + 1, 256) ;~ $j = Mod($j + $state[$i], 256) ;~ $n = $state[$i] ;~ $state[$i] = $state[$j] ;~ $state[$j] = $n ;~ $n = Mod($state[$i] + $state[$j], 256) ;~ DllStructSetData($tData, 1, BitXOR($state[$n], Int(DllStructGetData($tData, 1, $k))), $k) ;~ Next ; Return DllStructGetData($tData, 1) EndFunc ;==>__CS_Cipher Func __CS_Cleanup() If $__g_CS_pCode Then _MemVirtualFree($__g_CS_pCode, 0, $MEM_RELEASE) EndFunc ;==>__CS_Cleanup #endregion INTERNAL FUNCTIONS cipher.c void __stdcall cipher(unsigned char src[], int srcSize, unsigned char state[256]) { int c = 0, i = 0, j = 0, n = 0; for (c = 0; c < srcSize; c++) { i = (i + 1) % 256; j = (j + state[i]) % 256; n = state[i]; state[i] = state[j]; state[j] = n; src[c] = state[((state[i] + state[j]) % 256)] ^ src[c]; } } Example #include <_CipherSaber.au3> ; NOTE: the IV is random data, so the encrypted data is different each time $p = "mypassword" ; string $s = "Some string to encrypt" $e = _CipherSaber(StringToBinary($s), $p) ConsoleWrite("encrypted: " & $e & @CRLF) ; $e is already binary data, default number of key rounds is 20, set flag to decrypt ; returned decrypted data is also binary $d = _CipherSaber($e, $p, 20, False) ConsoleWrite("decrypted: " & BinaryToString($d) & @CRLF) ConsoleWrite("---------------------" & @CRLF) ; file $f = @DesktopDir & "\in.txt" $o = @DesktopDir & "\enc.txt" $o2 = @DesktopDir & "\dec.txt" FileWrite($f, "Some sensitive file") ConsoleWrite("original file: " & Binary(FileRead($f)) & @CRLF) _CipherSaber_File($f, $o, $p) ConsoleWrite("encrypted file: " & Binary(FileRead($o)) & @CRLF) ; default key rounds 20, flag to decrypt _CipherSaber_File($o, $o2, $p, 20, False) ConsoleWrite("decrypted file: " & Binary(FileRead($o2)) & @CRLF) ; cleanup FileDelete($f) FileDelete($o) FileDelete($o2)
- 6 replies
-
- ciphersaber
- rc4
-
(and 1 more)
Tagged with: