Sample code for 30+ languages & platforms
AutoIt

Duplicate SQL Server ENCRYPTBYPASSPHRASE

See more Encryption Examples

Demonstrates how to duplicate SQL Server's ENCRYPTBYPASSPHRASE.

Chilkat AutoIt Downloads

AutoIt
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.

; For SQL Server 2008 - SQL Server 2016 we must use TripleDES with SHA1
; For SQL Server 2017 and later, use AES256 / SHA256.

Local $sPassword = "tEst1234"
Local $sEncryptedHex_v1 = "0x010000001E8E7DCDBD4061B951999E25D18445D2305474D2D71EEE98A241C755246F58AB"

; Here's an encrypted string using AES256/SHA256
Local $sEncryptedHex_v2 = "0x02000000FFE880C0354780481E64EF25B6197A02E2A854A4BA9D8D9BDDFDAB27EB56537ABDA0B1D9C4D1050C91B313550DECF429"

$oSbEncHex = ObjCreate("Chilkat.StringBuilder")
$oSbEncHex.Append($sEncryptedHex_v1)

; If present, we don't want the leading "0x"
If ($oSbEncHex.StartsWith("0x",False) = True) Then
    $oSbEncHex.RemoveCharsAt(0,2)
EndIf

$oCrypt = ObjCreate("Chilkat.Crypt2")
$oCrypt.EncodingMode = "hex"

; The encrypted hex string will begin with either 01000000 or 02000000
; version 1 is produced by SQL Server 2008 to SQL Server 2016, and we must use TripleDES with SHA1
; version 2 is for SQL Server 2017 and later, and uses AES256 / SHA256.
Local $bV1 = $oSbEncHex.StartsWith("01",False)

Local $ivLen = 0
Local $sHashAlg

If ($bV1 = True) Then
    $oCrypt.CryptAlgorithm = "3des"
    $oCrypt.CipherMode = "cbc"
    $oCrypt.KeyLength = 168
    $ivLen = 8
    $sHashAlg = "sha1"
Else
    $oCrypt.CryptAlgorithm = "aes"
    $oCrypt.CipherMode = "cbc"
    $oCrypt.KeyLength = 256
    $ivLen = 16
    $sHashAlg = "sha256"
EndIf

; Remove the SQL Server version info (i.e. the "01000000")
$oSbEncHex.RemoveCharsAt(0,8)

; Get the IV part of the sbEncHex, and also remove it from the StringBuilder.
Local $sIvHex = $oSbEncHex.GetRange(0,$ivLen * 2,True)
ConsoleWrite("IV = " & $sIvHex & @CRLF)
$oCrypt.SetEncodedIV $sIvHex,"hex"

$oSbPassword = ObjCreate("Chilkat.StringBuilder")
$oSbPassword.Append($sPassword)
Local $sPwd_hash = $oSbPassword.GetHash($sHashAlg,"hex","utf-16")
$oSbKey = ObjCreate("Chilkat.StringBuilder")
$oSbKey.Append($sPwd_hash)
If ($bV1 = True) Then
    ; For v1, we only want the 1st 16 bytes of the 20 byte hash.
    ; (remember, the hex encoding uses 2 chars per byte, so we remove the last 8 chars)
    $oSbKey.Shorten(8)
EndIf

ConsoleWrite("crypt key: " & $oSbKey.GetAsString() & @CRLF)

$oCrypt.SetEncodedKey $oSbKey.GetAsString(),"hex"

; Decrypt
$oBd = ObjCreate("Chilkat.BinData")
$oBd.AppendEncoded($oSbEncHex.GetAsString(),"hex")
$oCrypt.DecryptBd($oBd)

; The result is composed of a header of 8 bytes which we can discard.
; The remainder is the decrypted text.

; The header we are discarding is composed of:
; Bytes 0-3: Magic number equal to 0DF0ADBA
; Bytes 4-5: Number of integrity bytes, which is 0 unless an authenticator is used. We're assuming no authenticator is used.
; Bytes 6-7: Number of plain-text bytes. We really don't need this because the CBC padding takes care of it.

; Therefore, just return the data after the 1st 8 bytes.
; Assuming the encrypted string was utf-8 text...
$oBd.RemoveChunk(0,8)
Local $sPlainText = $oBd.GetString("utf-8")
ConsoleWrite("decrypted plain text: " & $sPlainText & @CRLF)

; The output:

; IV = 1E8E7DCDBD4061B9
; crypt key: 710B9C2E61ACCC9570D4112203BD9738
; decrypted plain text: Hello world.

; ------------------------------------------------------------------------------------------
; To encrypt, do the reverse...

; Let's do v1 with TripleDES with SHA1

$oEncryptor = ObjCreate("Chilkat.Crypt2")
$oEncryptor.EncodingMode = "hex"

$oEncryptor.CryptAlgorithm = "3des"
$oEncryptor.CipherMode = "cbc"
$oEncryptor.KeyLength = 168

; Generate a random 8-byte IV
$oPrng = ObjCreate("Chilkat.Prng")
$sIvHex = $oPrng.GenRandom(8,"hex")
$oEncryptor.SetEncodedIV $sIvHex,"hex"

; The binary password is generated the same as above.
; We'll use the same password (and same binary password)
$oEncryptor.SetEncodedKey $oSbKey.GetAsString(),"hex"

Local $iPlainTextLen = 8
$sPlainText = "ABCD1234"

; Encrypt the header + the plain-text.
$oBdData = ObjCreate("Chilkat.BinData")
$oBdData.AppendEncoded("0DF0ADBA","hex")
$oBdData.AppendEncoded("0000","hex")
$oBdData.AppendInt2($iPlainTextLen,True)
ConsoleWrite("header: " & $oBdData.GetEncoded("hex") & @CRLF)
$oBdData.AppendString($sPlainText,"utf-8")
$oEncryptor.EncryptBd($oBdData)

; Compose the result..
$oSbEnc = ObjCreate("Chilkat.StringBuilder")
$oSbEnc.Append("0x01000000")
$oSbEnc.Append($sIvHex)
$oSbEnc.Append($oBdData.GetEncoded("hex"))

ConsoleWrite("result: " & $oSbEnc.GetAsString() & @CRLF)