AutoIt
AutoIt
Duplicate SQL Server ENCRYPTBYPASSPHRASE
See more Encryption Examples
Demonstrates how to duplicate SQL Server's ENCRYPTBYPASSPHRASE.Chilkat AutoIt Downloads
; 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)