Sample code for 30+ languages & platforms
Tcl

Example: Crypt2.RandomizeIV method

Demonstrates using a random initialization vector for AES GCM encryption.

Chilkat Tcl Downloads

Tcl

load ./chilkat.dll

set success 0

# This example assumes the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.

set crypt [new_CkCrypt2]

CkCrypt2_put_CryptAlgorithm $crypt "aes"
CkCrypt2_put_CipherMode $crypt "gcm"
CkCrypt2_put_KeyLength $crypt 256

set K "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"
set AAD "feedfacedeadbeeffeedfacedeadbeefabaddad2"
set PT "This is the text to be AES-GCM encrypted."

# Generate a random IV.
CkCrypt2_RandomizeIV $crypt
set IV [CkCrypt2_getEncodedIV $crypt "hex"]

CkCrypt2_SetEncodedKey $crypt $K "hex"

set success [CkCrypt2_SetEncodedAad $crypt $AAD "hex"]

# Return the encrypted bytes as base64
CkCrypt2_put_EncodingMode $crypt "base64"
CkCrypt2_put_Charset $crypt "utf-8"
set cipherText [CkCrypt2_encryptStringENC $crypt $PT]
if {[CkCrypt2_get_LastMethodSuccess $crypt] != 1} then {
    puts [CkCrypt2_lastErrorText $crypt]
    delete_CkCrypt2 $crypt
    exit
}

# Get the GCM authenticated tag computed when encrypting.
set authTag [CkCrypt2_getEncodedAuthTag $crypt "base64"]

puts "Cipher Text: $cipherText"
puts "Auth Tag: $authTag"

# Let's send the IV, CipherText, and AuthTag to the decrypting party.
# We'll send them concatenated like this: [IV || Ciphertext || AuthTag]
# In base64 format.
set bdEncrypted [new_CkBinData]

CkBinData_AppendEncoded $bdEncrypted $IV "hex"
CkBinData_AppendEncoded $bdEncrypted $cipherText "base64"
CkBinData_AppendEncoded $bdEncrypted $authTag "base64"

set concatenatedGcmOutput [CkBinData_getEncoded $bdEncrypted "base64"]
puts "Concatenated GCM Output: $concatenatedGcmOutput"

# Sample output so far:

# -------------------------------------------------------------------------------------
# Now let's GCM decrypt...
# -------------------------------------------------------------------------------------

set decrypt [new_CkCrypt2]

# The values shared and agreed upon by both sides beforehand are: algorithm, cipher mode, secret key, and AAD.
# Sometimes the IV can be a value already known and agreed upon, but in this case the encryptor sends the IV to the decryptor.
CkCrypt2_put_CryptAlgorithm $decrypt "aes"
CkCrypt2_put_CipherMode $decrypt "gcm"
CkCrypt2_put_KeyLength $decrypt 256
CkCrypt2_SetEncodedKey $decrypt $K "hex"
CkCrypt2_SetEncodedAad $decrypt $AAD "hex"

set bdFromEncryptor [new_CkBinData]

CkBinData_AppendEncoded $bdFromEncryptor $concatenatedGcmOutput "base64"

set sz [CkBinData_get_NumBytes $bdFromEncryptor]

# Extract the parts.
set extractedIV [CkBinData_getEncodedChunk $bdFromEncryptor 0 16 "hex"]
set extractedCipherText [CkBinData_getEncodedChunk $bdFromEncryptor 16 [expr $sz - 32] "base64"]
set expectedAuthTag [CkBinData_getEncodedChunk $bdFromEncryptor [expr $sz - 16] 16 "base64"]

# Before GCM decrypting, we must set the authenticated tag to the value that is expected.
# The decryption will fail if the resulting authenticated tag is not equal to the expected result.
set success [CkCrypt2_SetEncodedAuthTag $decrypt $expectedAuthTag "base64"]

# Also set the IV.
CkCrypt2_SetEncodedIV $decrypt $extractedIV "hex"

# Decrypt..
CkCrypt2_put_EncodingMode $decrypt "base64"
CkCrypt2_put_Charset $decrypt "utf-8"
set decryptedText [CkCrypt2_decryptStringENC $decrypt $extractedCipherText]
if {[CkCrypt2_get_LastMethodSuccess $decrypt] != 1} then {
    # Failed.  The resultant authenticated tag did not equal the expected authentication tag.
    puts [CkCrypt2_lastErrorText $decrypt]
    delete_CkCrypt2 $crypt
    delete_CkBinData $bdEncrypted
    delete_CkCrypt2 $decrypt
    delete_CkBinData $bdFromEncryptor
    exit
}

puts "Decrypted: $decryptedText"

delete_CkCrypt2 $crypt
delete_CkBinData $bdEncrypted
delete_CkCrypt2 $decrypt
delete_CkBinData $bdFromEncryptor