Jump to content

DES Encryption


Recommended Posts

I was in need of the DES encryption within AutoIt, hoping to use that value with a similar script in a comparison from a web page that has DES implemented (just in PHP). I was able to get my hands on the DES function that I wanted to use on the PHP side, but when I converted it to AutoIt, I apparently missed something. I've been working on this since about 10 last night (total of around 10 hours), and I can't figure out where I missed the change, so, I was hoping someone here could help me. Now, I know, (as quoting from the Pink Box Above) "This is not a gerneral support forum!. The reason I am posting it here still, is, even though it is not "the" DES encryption function, it is still "an" encryption function, that produces results similar to DES, but if anyone were trying to attack it, they wouldn't be able to with standard DES tools (at least, that's my theory).

So, here is the AutoIt DES Encryption function (almost):

_linenums:0'>
;===============================================================================
; Autoit Version
; Matthew Robinson, April 2007
; Based on...
;
;PHP version
;Paul Tero, July 2001
;http://www.tero.co.uk/des/
;
;Optimised for performance with large blocks by Michael Hayworth, November 2001
;http://www.netdealing.com
;
;Converted from Javascript to PHP by Jim Gibbs, June 2004
;
;THIS SOFTWARE IS PROVIDED "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
;OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
;HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
;LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
;OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
;SUCH DAMAGE.
;===============================================================================

Local $key = "this is a 24 byte key !!"
Local $message = "This is a test message"
Local $ciphertext = des($key, $message, 1, 0, "")
ConsoleWrite("DES Test Encrypted: " & StringToHex($ciphertext))
$recovered_message = des($key, $ciphertext, 0, 0, "")
ConsoleWrite(@CRLF)
ConsoleWrite("DES Test Decrypted: " & $recovered_message)
ConsoleWrite(@CRLF)

;===================================================================
; des
; this takes the key, the message, and whether to encrypt or decrypt
;===================================================================
Func des($key, $message, $encrypt, $mode, $iv)
    ; declaring this locally speeds things up a bit
    Local $spfunction1[64] = [0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004]
    Local $spfunction2[64] = [-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000]
    Local $spfunction3[64] = [0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200]
    Local $spfunction4[64] = [0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080]
    Local $spfunction5[64] = [0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100]
    Local $spfunction6[64] = [0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010]
    Local $spfunction7[64] = [0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002]
    Local $spfunction8[64] = [0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000]
    Local $masks[33] = [4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0]

    ; create the 16 or 48 subkeys we will need
    Local $keys = des_createKeys($key)
    Local $m=0
    Local $len = StringLen($message)
    Local $chunk = 0
    ; set up the loops for single and triple des
    If UBound($keys) == 32 Then
        Local $iterations = 3
    Else
        Local $iterations = 9
    EndIf
    If $iterations == 3 Then
        If $encrypt == 1 Then
            Local $looping[3] = [0,32,2]
        Else
            Local $looping[3] = [30,-2,-2]
        EndIf
    Else
        If $encrypt == 1 Then
            Local $looping[9] = [0,32,2,62,30,-2,64,96,2]
        Else
            Local $looping[9] = [94,62,-2,32,64,2,30,-2,-2]
        EndIf
    EndIf

  $message &= Chr(0)&Chr(0)&Chr(0)&Chr(0)&Chr(0)&Chr(0)&Chr(0)&Chr(0) ; pad the message out with null bytes
  ; store the result here
  $result = ""
  $tempresult = ""

  If $mode == 1 Then ; CBC mode
    $cbcleft = Dec(Hex(Asc(StringMid($iv,1,1)),2) & Hex(Asc(StringMid($iv,2,1)),2) & Hex(Asc(StringMid($iv,3,1)),2) & Hex(Asc(StringMid($iv,4,1)),2))
    $cbcright = Dec(Hex(Asc(StringMid($iv,5,1)),2) & Hex(Asc(StringMid($iv,6,1)),2) & Hex(Asc(StringMid($iv,7,1)),2) & Hex(Asc(StringMid($iv,8,1)),2))
  EndIf

  ; loop through each 64 bit chunk of the message
  While ($m < $len)
    $left_temp = ""
    For $i = 1 to 4
        $left_temp &= Hex(Asc(StringMid($message,$m+1,1)),2)
        $m += 1
    Next
    $left = Dec($left_temp)
    
    $right_temp = ""
    For $i = 1 to 4
        $right_temp &= Hex(Asc(StringMid($message,$m+1,1)),2)
        $m += 1
    Next
    $right = Dec($right_temp)

    ; for Cipher Block Chaining mode, xor the message with the previous result
    If $mode == 1 Then 
        If $encrypt Then 
            $left = BitXOR($left, $cbcleft)
            $right = BitXOR($right, $cbcright)
        Else 
            $cbcleft2 = $cbcleft
            $cbcright2 = $cbcright
            $cbcleft = $left
            $cbcright = $right
        EndIf
    EndIf

    ; first each 64 bit chunk of the message must be permuted according to IP
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,4),$masks[4]), $right),0x0f0f0f0f)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-4)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,16),$masks[16]), $right), 0x0000ffff)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-16)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,2),$masks[2]), $left), 0x33333333)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,-2)))
    
    $temp = BitAnd(BitXOR(BitAND(BitShift($right,8),$masks[8]), $left), 0x00ff00ff)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,-8)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,1),$masks[1]), $right), 0x55555555)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-1)))
    
    $left = BitOR(BitShift($left,-1),BitAND(BitShift($left,31),$masks[31]))
    $right = BitOR(BitShift($right,-1),BitAND(BitShift($right,31),$masks[31])) 

    ; do this either 1 or 3 times for each chunk of the message
    $j = 0
    While $j < ($iterations-1)
      $endloop = $looping[$j+1];
      $loopinc = $looping[$j+2];
      ; now go through and perform the encryption or decryption
      $i = $looping[$j]
      While $i <> $endloop ; for efficiency
        $right1 = BitXOR($right,$keys[$i])
        $right2 = BitXOR(BitOR(BitAND(BitShift($right,4),$masks[4]),BitShift($right,-28)),$keys[$i+1])
        ; the result is attained by passing these bytes through the S selection functions
        $temp = $left
        $left = $right
        $right = BitXOR($temp,BitOR($spfunction2[BitAND(BitAND(BitShift($right1,24),$masks[24]),0x3f)],$spfunction4[BitAND(BitAND(BitShift($right1,16),$masks[16]),0x3f)],$spfunction6[BitAND(BitAND(BitShift($right1,8),$masks[8]),0x3f)],$spfunction8[BitAND($right1,0x3f)],$spfunction1[BitAND(BitAND(BitShift($right2,24),$masks[24]),0x3f)],$spfunction3[BitAND(BitAND(BitShift($right2,16),$masks[16]),0x3f)],$spfunction5[BitAND(BitAND(BitShift($right2,8),$masks[8]),0x3f)],$spfunction7[BitAND($right2,0x3f)]))
        $i += $loopinc
    WEnd
      ; unreverse left and right
      $temp = $left
      $left = $right 
      $right = $temp
    $j += 3
    WEnd ; for either 1 or 3 iterations

    ; move then each one bit to the right
    $left = BitOR(BitAND(BitShift($left,1),$masks[1]),BitShift($left,-31))
    $right = BitOR(BitAND(BitShift($right,1),$masks[1]),BitShift($right,-31))

    ; now perform IP-1, which is IP in the opposite direction
    $temp = BitAND(BitXOR(BitAND(BitShift($left,1),$masks[1]),$right),0x55555555)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-1)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,8),$masks[8]),$left),0x00ff00ff)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,-8)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,2),$masks[2]),$left),0x33333333)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,-2)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,16),$masks[16]),$right),0x0000ffff)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-16)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,4),$masks[4]),$right),0x0f0f0f0f)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-4)))
    

    ; for Cipher Block Chaining mode, xor the message with the previous result
    If $mode == 1 Then
        If $encrypt Then
            $cbcleft = $left
            $cbcright = $right
        Else 
            $left = BitXOR($left,$cbcleft2)
            $right = BitXOR($right,$cbcright2)
        EndIf
    EndIf
    $tempresult &= Chr(BitAND(BitShift($left,24),$masks[24]))
    $tempresult &= Chr(BitAnd(BitAND(BitShift($left,16),$masks[16]),0xff))
    $tempresult &= Chr(BitAND(BitAND(BitShift($left,8),$masks[8]),0xff))
    $tempresult &= Chr(BitAND($left,0xff))
    $tempresult &= Chr(BitAND(BitShift($right,24),$masks[24]))
    $tempresult &= Chr(BitAND(BitAND(BitShift($right,16),$masks[16]),0xff))
    $tempresult &= Chr(BitAND(BitAND(BitShift($right,8),$masks[8]),0xff))
    $tempresult &= Chr(BitAND($right,0xff))

    $chunk += 8;
    If $chunk == 512 Then
        $result &= $tempresult
        $tempresult = ""
        $chunk = 0
    EndIf
  WEnd ; for every 8 characters, or 64 bits in the message

  ; return the result as an array
  Return $result & $tempresult
EndFunc ; end of des


;=====================================================================
; des_createKeys
; this takes as input a 64 bit key (even though only 56 bits are used)
; as an array of 2 integers, and returns 16 48 bit keys
;=====================================================================

Func des_createKeys($key)
  ; declaring this locally speeds things up a bit
  Local $pc2bytes0[16]  = [0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204]
  Local $pc2bytes1[16]  = [0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101]
  Local $pc2bytes2[16]  = [0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808]
  Local $pc2bytes3[16]  = [0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000]
  Local $pc2bytes4[16]  = [0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010]
  Local $pc2bytes5[16]  = [0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420]
  Local $pc2bytes6[16]  = [0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002]
  Local $pc2bytes7[16]  = [0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800]
  Local $pc2bytes8[16]  = [0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002]
  Local $pc2bytes9[16]  = [0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408]
  Local $pc2bytes10[16] = [0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020]
  Local $pc2bytes11[16] = [0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200]
  Local $pc2bytes12[16] = [0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010]
  Local $pc2bytes13[16] = [0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105]
  Local $masks[33] = [4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0]

  ; how many iterations (1 for des, 3 for triple des)
  If StringLen($key) >= 24 Then
      Local $iterations = 3
  Else
      Local $iterations = 1
  EndIf
  
  ; stores the return keys
  Local $keys[1] = [32 * $iterations]
  ; now define the left shifts which need to be done
  Local $shifts[16] = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0]
  ; other variables
  Local $m=0, $n=0

  For $j = 0 To $iterations-1 ; either 1 or 3 iterations
    $left_temp = ""
    For $i = 1 to 4
        $left_temp = Hex(Asc(StringMid($key,$m+1,1)),2)
        $m += 1
    Next
    $left = Dec($left_temp)
    
    $right_temp = ""
    For $i = 1 to 4
        $right_temp = Hex(Asc(StringMid($key,$m+1,1)),2)
        $m += 1
    Next
    $right = Dec($right_temp)

    $temp = BitAnd(BitXOR(BitAND(BitShift($left,4),$masks[4]),$right),0x0f0f0f0f)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-4)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,16),$masks[16]),$left),0x0000ffff)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,16)))
    
    $temp = Bitand(BitXOR(BitAND(BitShift($left,2),$masks[2]),$right),0x33333333)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-2)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,16),$masks[16]),$left),0x0000ffff)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,16)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,1),$masks[1]),$right),0x55555555)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-1)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($right,8),$masks[8]),$left),0x00ff00ff)
    $left = BitXOR($left,$temp)
    $right = BitXOR($right,(BitShift($temp,-8)))
    
    $temp = BitAND(BitXOR(BitAND(BitShift($left,1),$masks[1]),$right),0x55555555)
    $right = BitXOR($right,$temp)
    $left = BitXOR($left,(BitShift($temp,-1)))
    

    ; the right side needs to be shifted and to get the last four bits of the left side
    $temp = BitOR(BitShift($left,-8),BitAND(BitAND(BitShift($right,20),$masks[20]),0x000000f0))
    ;left needs to be put upside down
    $left = BitOR(BitShift($right,-24),BitAND(BitShift($right,-8),0xff0000),BitAND(BitAND(BitShift($right,8),$masks[8]),0xff00),BitAND(BitAND(BitShift($right,24),$masks[24]),0xf0))
    $right = $temp

    ; now go through and perform these shifts on the left and right keys
    For $i = 0 To Ubound($shifts)-1
      ;shift the keys either one or two bits to the left
      If $shifts[$i] Then 
          $left = BitOR(BitShift($left,-2),BitAND(BitShift($left,26),$masks[26]))
          $right = BitOR(BitShift($right,-2),BitAND(BitShift($right,26),$masks[26]))
      Else
          $left = BitOR(BitShift($left,-1),BitAND(BitShift($left,27),$masks[27]))
          $right = BitOR(BitShift($right,-1),BitAND(BitShift($right,27),$masks[27]))
      EndIf
      $left = BitAND($left, -0xf)
      $right = BitAND($right, -0xf)

      ; now apply PC-2, in such a way that E is easier when encrypting or decrypting
      ; this conversion will look like PC-2 except only the last 6 bits of each byte are used
      ; rather than 48 consecutive bits and the order of lines will be according to 
      ; how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
      $lefttemp = BitOR($pc2bytes0[BitAND(BitShift($left,28),$masks[28])],$pc2bytes1[BitAND(BitAND(BitShift($left,24),$masks[24]),0xf)],$pc2bytes2[BitAND(BitAND(BitShift($left,20),$masks[20]),0xf)],$pc2bytes3[BitAND(BitAND(BitShift($left,16),$masks[16]),0xf)],$pc2bytes4[BitAND(BitAND(BitShift($left,12),$masks[12]),0xf)],$pc2bytes5[BitAND(BitAND(BitShift($left,8),$masks[8]),0xf)],$pc2bytes6[BitAND(BitAND(BitShift($left,4),$masks[4]),0xf)])
      $righttemp = BitOR($pc2bytes7[BitAND(BitShift($right,28),$masks[28])],$pc2bytes8[BitAND(BitAND(BitShift($right,24),$masks[24]),0xf)],$pc2bytes9[BitAND(BitAND(BitShift($right,20),$masks[20]),0xf)],$pc2bytes10[BitAND(BitAND(BitShift($right,16),$masks[16]),0xf)],$pc2bytes11[BitAND(BitAND(BitShift($right,12),$masks[12]),0xf)],$pc2bytes12[BitAND(BitAND(BitShift($right,8),$masks[8]),0xf)],$pc2bytes13[BitAND(BitAND(BitShift($right,4),$masks[4]),0xf)])
      $temp = BitAND(BitOR(BitAND(BitShift($righttemp,16),$masks[16]),$lefttemp),0x0000ffff)
      Redim $keys[$n+2]
      $keys[$n] = BitXOR($lefttemp,$temp)
      $n += 1
      $keys[$n] = BitXOR($righttemp,BitShift($temp,-16))
      $n += 1
    Next
  Next ; for each iterations
  ; return the keys we've created
  return $keys
EndFunc ; end of des_createKeys

Func stringToHex($s)
    Dim $result = "0x"
    Dim $temp = StringSplit($s,"")
    For $i = 1 to $temp[0]
        $result &= Hex(Asc($temp[$i]),2)
    Next
    
    Return $result
EndFunc

and, just for reference, I'll also include the PHP version I built this from:

_linenums:0'>
//PHP version
//Paul Tero, July 2001
//http://www.tero.co.uk/des/
//
//Optimised for performance with large blocks by Michael Hayworth, November 2001
//http://www.netdealing.com
//
//Converted from Javascript to PHP by Jim Gibbs, June 2004
//
//THIS SOFTWARE IS PROVIDED "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
//SUCH DAMAGE.

//des
//this takes the key, the message, and whether to encrypt or decrypt
function des ($key, $message, $encrypt, $mode, $iv) {
  //declaring this locally speeds things up a bit
  $spfunction1 = array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x10
00404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x100040
4,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x10
10400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x10
10404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10
004,0x10400,0,0x1010004);
  $spfunction2 = array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
  $spfunction3 = array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x
8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x
8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x
20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,
0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x2020
8,0x8,0x8020008,0x20200);
  $spfunction4 = array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,
0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x8
00080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x8
00080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x8
00081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
  $spfunction5 = array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x200
0100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x4000010
0,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,
0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40
000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42
080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100
,0x40000100);
  $spfunction6 = array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,
0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20
004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x2000
4000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0
x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400
000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
  $spfunction7 = array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002
,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0
x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,
0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x
200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0
x800,0x4000002,0x4000800,0x800,0x200002);
  $spfunction8 = array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x
10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40
040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x4000
0,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,
0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x1
0041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
  $masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,838860
7,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,
31,15,7,3,1,0);

  //create the 16 or 48 subkeys we will need
  $keys = des_createKeys ($key);
  $m=0;
  $len = strlen($message);
  $chunk = 0;
  //set up the loops for single and triple des
  $iterations = ((count($keys) == 32) ? 3 : 9); //single or triple des
  if ($iterations == 3) {$looping = (($encrypt) ? array (0, 32, 2) : array (30, -2, -2));}
  else {$looping = (($encrypt) ? array (0, 32, 2, 62, 30, -2, 64, 96, 2) : array (94, 62, -2, 32, 64, 2, 30, -2, -2));}

  $message .= (chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0)); //pad the message out with null bytes
  //store the result here
  $result = "";
  $tempresult = "";

  if ($mode == 1) { //CBC mode
    $cbcleft = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++});
    $cbcright = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++});
    $m=0;
  }

  //loop through each 64 bit chunk of the message
  while ($m < $len) {
    $left = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++});
    $right = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++});

    //for Cipher Block Chaining mode, xor the message with the previous result
    if ($mode == 1) {if ($encrypt) {$left ^= $cbcleft; $right ^= $cbcright;} else {$cbcleft2 = $cbcleft; $cbcright2 = $cbcright; $cbcleft = $left; $cbcright = $right;}}

    //first each 64 but chunk of the message must be permuted according to IP
    $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
    $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16);
    $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2);
    $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);

    $left = (($left << 1) | ($left >> 31 & $masks[31])); 
    $right = (($right << 1) | ($right >> 31 & $masks[31])); 

    //do this either 1 or 3 times for each chunk of the message
    for ($j=0; $j<$iterations; $j+=3) {
      $endloop = $looping[$j+1];
      $loopinc = $looping[$j+2];
      //now go through and perform the encryption or decryption  
      for ($i=$looping[$j]; $i!=$endloop; $i+=$loopinc) { //for efficiency
        $right1 = $right ^ $keys[$i]; 
        $right2 = (($right >> 4 & $masks[4]) | ($right << 28)) ^ $keys[$i+1];
        //the result is attained by passing these bytes through the S selection functions
        $temp = $left;
        $left = $right;
        $right = $temp ^ ($spfunction2[($right1 >> 24 & $masks[24]) & 0x3f] | $spfunction4[($right1 >> 16 & $masks[16]) & 0x3f]
              | $spfunction6[($right1 >>  8 & $masks[8]) & 0x3f] | $spfunction8[$right1 & 0x3f]
              | $spfunction1[($right2 >> 24 & $masks[24]) & 0x3f] | $spfunction3[($right2 >> 16 & $masks[16]) & 0x3f]
              | $spfunction5[($right2 >>  8 & $masks[8]) & 0x3f] | $spfunction7[$right2 & 0x3f]);
      }
      $temp = $left; $left = $right; $right = $temp; //unreverse left and right
    } //for either 1 or 3 iterations

    //move then each one bit to the right
    $left = (($left >> 1 & $masks[1]) | ($left << 31)); 
    $right = (($right >> 1 & $masks[1]) | ($right << 31)); 

    //now perform IP-1, which is IP in the opposite direction
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
    $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
    $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2);
    $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16);
    $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);

    //for Cipher Block Chaining mode, xor the message with the previous result
    if ($mode == 1) {if ($encrypt) {$cbcleft = $left; $cbcright = $right;} else {$left ^= $cbcleft2; $right ^= $cbcright2;}}
    $tempresult .= (chr($left>>24 & $masks[24]) . chr(($left>>16 & $masks[16]) & 0xff) . chr(($left>>8 & $masks[8]) & 0xff) . chr($left & 0xff) . chr($right>>24 & $masks[24]) . chr(($right>>16 & $masks[16]) & 0xff) . chr(($right>>8 & $masks[8]) & 0xff) . chr($right & 0xff));

    $chunk += 8;
    if ($chunk == 512) {$result .= $tempresult; $tempresult = ""; $chunk = 0;}
  } //for every 8 characters, or 64 bits in the message

  //return the result as an array
  return ($result . $tempresult);
} //end of des

//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys ($key) {
  //declaring this locally speeds things up a bit
  $pc2bytes0  = array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000
204,0x10200,0x10204,0x20010200,0x20010204);
  $pc2bytes1  = array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x
4000100,0x4000101,0x4100100,0x4100101);
  $pc2bytes2  = array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,
0x1000800,0x1000808);
  $pc2bytes3  = array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x
8220000,0x22000,0x222000,0x8022000,0x8222000);
  $pc2bytes4  = array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x101
0,0x41010);
  $pc2bytes5  = array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x200040
0,0x2000020,0x2000420);
  $pc2bytes6  = array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x1008000
0,0x2,0x10000002,0x80002,0x10080002);
  $pc2bytes7  = array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30
800,0x20020000,0x20030000,0x20020800,0x20030800);
  $pc2bytes8  = array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x
2040002,0x2000002,0x2040002);
  $pc2bytes9  = array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,
0x10000400,0x408,0x10000408);
  $pc2bytes10 = array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,
0x102000,0x102020);
  $pc2bytes11 = array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,
0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
  $pc2bytes12 = array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010
,0x80010,0x81010,0x8080010,0x8081010);
  $pc2bytes13 = array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
  $masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,838860
7,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,
31,15,7,3,1,0);

  //how many iterations (1 for des, 3 for triple des)
  $iterations = ((strlen($key) >= 24) ? 3 : 1);
  //stores the return keys
  $keys = array (); // size = 32 * iterations but you don't specify this in php
  //now define the left shifts which need to be done
  $shifts = array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
  //other variables
  $m=0;
  $n=0;

  for ($j=0; $j<$iterations; $j++) { //either 1 or 3 iterations
    $left = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});
    $right = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});

    $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
    $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << -16);
    $temp = (($left >> 2 & $masks[2]) ^ $right) & 0x33333333; $right ^= $temp; $left ^= ($temp << 2);
    $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << -16);
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
    $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);

    //the right side needs to be shifted and to get the last four bits of the left side
    $temp = ($left << 8) | (($right >> 20 & $masks[20]) & 0x000000f0);
    //left needs to be put upside down
    $left = ($right << 24) | (($right << 8) & 0xff0000) | (($right >> 8 & $masks[8]) & 0xff00) | (($right >> 24 & $masks[24]) & 0xf0);
    $right = $temp;

    //now go through and perform these shifts on the left and right keys
    for ($i=0; $i < count($shifts); $i++) {
      //shift the keys either one or two bits to the left
      if ($shifts[$i] > 0) {
         $left = (($left << 2) | ($left >> 26 & $masks[26]));
         $right = (($right << 2) | ($right >> 26 & $masks[26]));
      } else {
         $left = (($left << 1) | ($left >> 27 & $masks[27]));
         $right = (($right << 1) | ($right >> 27 & $masks[27]));
      }
      $left = $left & -0xf;
      $right = $right & -0xf;

      //now apply PC-2, in such a way that E is easier when encrypting or decrypting
      //this conversion will look like PC-2 except only the last 6 bits of each byte are used
      //rather than 48 consecutive bits and the order of lines will be according to 
      //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
      $lefttemp = $pc2bytes0[$left >> 28 & $masks[28]] | $pc2bytes1[($left >> 24 & $masks[24]) & 0xf]
              | $pc2bytes2[($left >> 20 & $masks[20]) & 0xf] | $pc2bytes3[($left >> 16 & $masks[16]) & 0xf]
              | $pc2bytes4[($left >> 12 & $masks[12]) & 0xf] | $pc2bytes5[($left >> 8 & $masks[8]) & 0xf]
              | $pc2bytes6[($left >> 4 & $masks[4]) & 0xf];
      $righttemp = $pc2bytes7[$right >> 28 & $masks[28]] | $pc2bytes8[($right >> 24 & $masks[24]) & 0xf]
                | $pc2bytes9[($right >> 20 & $masks[20]) & 0xf] | $pc2bytes10[($right >> 16 & $masks[16]) & 0xf]
                | $pc2bytes11[($right >> 12 & $masks[12]) & 0xf] | $pc2bytes12[($right >> 8 & $masks[8]) & 0xf]
                | $pc2bytes13[($right >> 4 & $masks[4]) & 0xf];
      $temp = (($righttemp >> 16 & $masks[16]) ^ $lefttemp) & 0x0000ffff; 
      $keys[$n++] = $lefttemp ^ $temp; $keys[$n++] = $righttemp ^ ($temp << 16);
    }
  } //for each iterations
  //return the keys we've created
  return $keys;
} //end of des_createKeys

////////////////////////////// TEST //////////////////////////////
function stringToHex ($s) {
  $r = "0x";
  $hexes = array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
  for ($i=0; $i<strlen($s); $i++) {$r .= ($hexes [(ord($s{$i}) >> 4)] . $hexes [(ord($s{$i}) & 0xf)]);}
  return $r;
}
echo "<PRE>";
$key = "this is a 24 byte key !!";
$message = "This is a test message";
$ciphertext = des ($key, $message, 1, 0, null);
echo "DES Test Encrypted: " . stringToHex ($ciphertext);
$recovered_message = des ($key, $ciphertext, 0, 0, null);
echo "\n";
echo "DES Test Decrypted: " . $recovered_message;

I hope someone else can find some use for all this, or possibly even help me fix it to work correctly. I think the problem is I could not for the life of me figure out how to do a Left Shift to -16, because in Autoit, BitShift($value, -16) is a Left Shift 16, so, in my thinking, BitShift($value, 16) is a LeftShift -16, but it's also a RightShift, and if it were just a right shift period, then why didn't they just put >> 16 in the PHP code, and not << -16?

I tried for the longest to solve my own problem, but Google (for once) was absolutely no help. Apparently, you cannot search for the "<<" characters, because it will not work. So, I come before you all, asking to see if anyone here can help me figure this out. If not, just have fun with the function up there (rename it if you don't want to confuse it for the real des). Thanks in advance.

Edited by SkinnyWhiteGuy
Link to comment
Share on other sites

In the PHP the character "<" has probably been replaced with the HTML code for that which is "&lt;" . If that is correct then ">" will have been replaced with "&gt;"

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

In the PHP the character "<" has probably been replaced with the HTML code for that which is "&lt;" . If that is correct then ">" will have been replaced with "&gt;"

Uh, thanks, I guess. I know how HTML encoded characters work, that isn't the issue. Google can't search for < at all, it returns no results, no error.

The real issue is with Left Bit Shift. I need to know how PHP handles Left Shifting a number, like, -16. Like $right ^= ($temp << -16) Sets $right to equal the result of BitXOR of itself and the value of $temp after it has been BitShifted Left -16. I'm just not sure how that translates to Autoit, because I don't know if a << -16 is the same as >> 16, or if it's still the same as << 16, with a sign change, or if it's all together different, and I need to reinvent that function all together by hand.

Thanks anyway. I'll try using &lt; to search on Google with, but I don't think it will work too swimmingly. I imagine I'll get too many results dealing with HTML encoding. I'll try anyway.

Link to comment
Share on other sites

Ok, I've found out what my problem partly is. After some testing, I found out that, in PHP at least ($var >> -16) has the same output as ($var >> 16). I'm still not sure why the original author did this, but I made script after script to loop through variables and print out any differences, and I couldn't find a single one. I fixed that, but the problem of not matching other DES scripts continued.

After a lot of searching and experimenting, I discovered the difference. In the PHP version, every last BitShift Right is done with >>>, which is BitShift Right Zero Fill. In AutoIt, the BitShift($var, $num) with $num being positive actually correlates to the PHP >> operator, which keeps the sign from the old number. In keeping signs, it changes how the encryption works, without actually breaking it. Very interesting.

Well, apparently finding the problem was one thing, finding a solution for the problem is another matter all together. Anyone else out there with more knowledge in Bitwise Shifts and all that, please help, otherwise, I'm going to keep on fighting to figure this out eventually.

Link to comment
Share on other sites

Well I'm not sure what DES is but good job any ways! :runs off to search for DES on wikipedia:

nice job

could you pls put the code in "[ codebox][ autoit] ... [ autoit][ codebox]" tags, the stupid forum messed up the code..

Edited by mrRevoked
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

Well I'm not sure what DES is but good job any ways! :runs off to search for DES on wikipedia:

Well, not to spoil your searching, but DES is an encryption algorithm. I saw (in some older posts) that others had wanted this function possibly built in to AutoIt. I like encryption and hashing stuff, and found that other source code for it in PHP (as well as versions in Javascript and Perl), and thought if those languages can do it, surely AutoIt can do it too. And, technically, it can. I'm just having difficulty making it provide the exact same encrypted string as other implementations.

I have one version that I did with nothing but strings, and it works perfectly. It's just very slow, and I used strings for binary numbers and did operations on those (explains the slowness). I wrote it based on the actual DES implementation (the above code is optimized). I want to try to convert it to using real numbers, and no more strings, but I'm still lacking in Bit-oriented math to correctly pull that off, as well as I don't think some of AutoIt's functions can handle it (most of the math is done on 64-Bit values, while alot of AutoIt's Bit Functions use & return 32-bit values).

Any other encryption nuts out there, when I figure this out, I'm going to try to combine it and some other crypo functions I've found here and elsewhere, and put together a Library of sorts for as many of the regular encryption/hashing schemes that are out there that I can implement. I hope someone other than me can find some use out of stuff like that.

Edit: Thanks for telling me how to do that, I couldn't figure that out when I first posted the above. First post Fixed now.

Edited by SkinnyWhiteGuy
Link to comment
Share on other sites

Well, I feel a little bit stupid this morning. It turns out that PHP can't do Zero Shifting either, and that's what the masks are for in the PHP code. The site I found that on has the DES algorithm in PHP, as well as Javascript and Perl. Turns out I was looking at the wrong place when I wrote about that. Oops.

Well, I've redone the code 3 times now, and I keep getting different results, none of which are like my pure string implementation. I have managed to narrow it down to the des_createkeys function. Now that I understand a good bit more how the optimized version works, I think I can begin to fix it and make it work correctly.

At any rate, by the end of today, a working DES algorithm will be posted, even if it has to be my stringed-out version of it.

Link to comment
Share on other sites

Well, I decided to redo it one last time, this time, using the Javascript source for the bulk of the code, and adding the masks trick from the PHP source, and...

IT WORKED!!!! :shocked::(:P;):sorcerer:

I don't know what is so different between the Javascript and PHP versions of the key creation function, but apparently, it's enough to cause problems. At any rate, I have the solution, and it works SO much faster than my Stringed-Out version. I still think I may try to convert parts of the String Version to Numeric versions, just to see if I can, and as a learning experience.

Any way, I'm attaching both scripts here, Des.au3 is the stringed version that works just like it's supposed to. Des_Optimized.au3 is the converted script from Javascript/PHP that runs super fast, and has a lot of extra features (CBC mode w/ 8byte input vectors, support for Triple DES by providing a 24 byte Key).

Now that this is done, I'll hunt down some more AutoIt only encryption/hashing functions, and put together the Cryptography library I'd love to see implemented.

Edit: Posted Scripts removed from this post, they are now available with several others in an archive at the following location:

Crypto Suite

Edited by SkinnyWhiteGuy
Link to comment
Share on other sites

I know, I plan on "extensive" searches before coding anything. I've already found Base64, MD5 (external process, creating a vb file to do it on the fly, and an internal version), and RC4 as well. I'm just trying to collect them all now, make sure they work as advertised (purely in AutoIt, as well), and then try to make sure they all have at least similar syntax. Hopefully I can get them all to be UDF quality (that is, if I find enough want for them).

Link to comment
Share on other sites

nice job!.. i suggest looking into AES, RSA, sha1, sha2, MD4, MD5, ect i've tried converting a couple but it kicked my ass.. (way to repetive!!) if you want ill send you some of my attempts.. some are almost complete..

also here some ideas.. http://www.cryptolounge.org/wiki/Category:Algorithm

that would be awesome to have the 'big boy' encryption library in autoit..

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Link to comment
Share on other sites

Just so you know, DES is not secure as an encryption algorythm. the method of creating the sub keys etc leaves it really easy to hack. (not that its not a good way to learn encryption, to start on a block cipher like DES then work up.) .

I would suggest Blowfish for a secure yet easy to implement algorythm (i have written code in C from scratch), then work up to AES. I also have md5 and sha1 in C. I would also suggest you look at Arcfour as a simple stream cipher to leran from. ( i also have written this in C) Arcfour is the www version of RC4 from RSA. It is an implementation of the theory from RC4 witout the patent issues (its used in Ciphersabre)

I am new to Autoit, so i wont suggest that i cdoe the libray but if you want example code in C then ill submit it for you.

RSA would be very difficult to implement due to the large prime generation required for the key generation., as it requires prime numbers in the region of 100 characters long or longer.

Link to comment
Share on other sites

I knew that DES, as it is, isn't very secure. It's only recommended as secure in its Triple Form, and even then AES is still preferred.

I've got AES already worked out from the FIPS-197 document. It works (albeit, slow). I'm currently converting an optimized AES script (in Javascript again) that was made from what GnuPG uses. When I get it done and working, I'll post those two on the forum.

And yeah, I'm just learning how to do this for fun really, during free time at work/home. It's fun for me, taking other code and making it work. When I finally "got it", I loved working with the FIPS-197 spec for Rijndael(AES). I might look into Blowfish next, just for fun. AES wasn't really that hard to understand, except for the GF(256) stuff, and I did kinda understand, I just couldn't get AutoIt to do a Mod like they wanted. Oh well, I got it working any way.

Link to comment
Share on other sites

Even Triple DES is insecure. Granted its more secure than DES, but given a long enough message (the encrypted data transmitted) it is easy to crack.

Blowfish like DES is a fiestel network, meaning it takes the data and splits it into 2*32bit parts (64bit cipher). Then it encrypts and swaps the pairs an even number of times (the suggested secure min is 16 times and this is the standard, but you could do it more if you dont mind the time/data ratio to be effected). Also you could implement Twofish, the entracnt for AES from the guys who wrote Blowfish (some say its a better algo, it is just slightly slower)

Also i was thinking about the suggestion made about RSA. Not only would it be difficult to generate the math, but RSA isnt actually used to encrypt a message (neither is any other Public key algo because they are too slow and the key length has to be almost twice that of symetric algos for encrypting long messages.). What happens when you use RSA is a password (key) for symetric encryption is encrypted using the public key algos, then this key is used for symetric encryption. This makes it easier to give the key out, as no one can reverse the RSA without the private key. This password is the same all the time (added when the public and private key pairs are generated) as it is time consuming to generate the key pairs.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...