PureBasic
PureBasic
Example: Crypt2.RandomizeIV method
Demonstrates using a random initialization vector for AES GCM encryption.Chilkat PureBasic Downloads
IncludeFile "CkCrypt2.pb"
IncludeFile "CkBinData.pb"
Procedure ChilkatExample()
success.i = 0
; This example assumes the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
crypt.i = CkCrypt2::ckCreate()
If crypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCrypt2::setCkCryptAlgorithm(crypt, "aes")
CkCrypt2::setCkCipherMode(crypt, "gcm")
CkCrypt2::setCkKeyLength(crypt, 256)
K.s = "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"
AAD.s = "feedfacedeadbeeffeedfacedeadbeefabaddad2"
PT.s = "This is the text to be AES-GCM encrypted."
; Generate a random IV.
CkCrypt2::ckRandomizeIV(crypt)
IV.s = CkCrypt2::ckGetEncodedIV(crypt,"hex")
CkCrypt2::ckSetEncodedKey(crypt,K,"hex")
success = CkCrypt2::ckSetEncodedAad(crypt,AAD,"hex")
; Return the encrypted bytes as base64
CkCrypt2::setCkEncodingMode(crypt, "base64")
CkCrypt2::setCkCharset(crypt, "utf-8")
cipherText.s = CkCrypt2::ckEncryptStringENC(crypt,PT)
If CkCrypt2::ckLastMethodSuccess(crypt) <> 1
Debug CkCrypt2::ckLastErrorText(crypt)
CkCrypt2::ckDispose(crypt)
ProcedureReturn
EndIf
; Get the GCM authenticated tag computed when encrypting.
authTag.s = CkCrypt2::ckGetEncodedAuthTag(crypt,"base64")
Debug "Cipher Text: " + cipherText
Debug "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.
bdEncrypted.i = CkBinData::ckCreate()
If bdEncrypted.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkBinData::ckAppendEncoded(bdEncrypted,IV,"hex")
CkBinData::ckAppendEncoded(bdEncrypted,cipherText,"base64")
CkBinData::ckAppendEncoded(bdEncrypted,authTag,"base64")
concatenatedGcmOutput.s = CkBinData::ckGetEncoded(bdEncrypted,"base64")
Debug "Concatenated GCM Output: " + concatenatedGcmOutput
; Sample output so far:
; -------------------------------------------------------------------------------------
; Now let's GCM decrypt...
; -------------------------------------------------------------------------------------
decrypt.i = CkCrypt2::ckCreate()
If decrypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; 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::setCkCryptAlgorithm(decrypt, "aes")
CkCrypt2::setCkCipherMode(decrypt, "gcm")
CkCrypt2::setCkKeyLength(decrypt, 256)
CkCrypt2::ckSetEncodedKey(decrypt,K,"hex")
CkCrypt2::ckSetEncodedAad(decrypt,AAD,"hex")
bdFromEncryptor.i = CkBinData::ckCreate()
If bdFromEncryptor.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkBinData::ckAppendEncoded(bdFromEncryptor,concatenatedGcmOutput,"base64")
sz.i = CkBinData::ckNumBytes(bdFromEncryptor)
; Extract the parts.
extractedIV.s = CkBinData::ckGetEncodedChunk(bdFromEncryptor,0,16,"hex")
extractedCipherText.s = CkBinData::ckGetEncodedChunk(bdFromEncryptor,16,sz - 32,"base64")
expectedAuthTag.s = CkBinData::ckGetEncodedChunk(bdFromEncryptor,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.
success = CkCrypt2::ckSetEncodedAuthTag(decrypt,expectedAuthTag,"base64")
; Also set the IV.
CkCrypt2::ckSetEncodedIV(decrypt,extractedIV,"hex")
; Decrypt..
CkCrypt2::setCkEncodingMode(decrypt, "base64")
CkCrypt2::setCkCharset(decrypt, "utf-8")
decryptedText.s = CkCrypt2::ckDecryptStringENC(decrypt,extractedCipherText)
If CkCrypt2::ckLastMethodSuccess(decrypt) <> 1
; Failed. The resultant authenticated tag did not equal the expected authentication tag.
Debug CkCrypt2::ckLastErrorText(decrypt)
CkCrypt2::ckDispose(crypt)
CkBinData::ckDispose(bdEncrypted)
CkCrypt2::ckDispose(decrypt)
CkBinData::ckDispose(bdFromEncryptor)
ProcedureReturn
EndIf
Debug "Decrypted: " + decryptedText
CkCrypt2::ckDispose(crypt)
CkBinData::ckDispose(bdEncrypted)
CkCrypt2::ckDispose(decrypt)
CkBinData::ckDispose(bdFromEncryptor)
ProcedureReturn
EndProcedure