Sample code for 30+ languages & platforms
Zig

Example: Crypt2.RandomizeIV method

Demonstrates using a random initialization vector for AES GCM encryption.

Chilkat Zig Downloads

Zig
const std = @import("std");
const chilkat = @import("chilkat");

pub fn main(init: std.process.Init) !void {
    const alloc = init.arena.allocator();

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

    const crypt = try chilkat.Crypt2.init();
    defer crypt.deinit();

    crypt.setCryptAlgorithm("aes");
    crypt.setCipherMode("gcm");
    crypt.setKeyLength(256);

    const k = "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F";
    const aad = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
    const pt = "This is the text to be AES-GCM encrypted.";

    // Generate a random IV.
    crypt.randomizeIV();
    const iv = try crypt.getEncodedIV(alloc, "hex");

    crypt.setEncodedKey(k, "hex");

    try crypt.setEncodedAad(aad, "hex");

    // Return the encrypted bytes as base64
    crypt.setEncodingMode("base64");
    crypt.setCharset("utf-8");
    const cipher_text = crypt.encryptStringENC(alloc, pt) catch {
        std.debug.print("{s}\n", .{try crypt.getLastErrorText(alloc)});
        return;
    };

    // Get the GCM authenticated tag computed when encrypting.
    const auth_tag = try crypt.getEncodedAuthTag(alloc, "base64");

    std.debug.print("Cipher Text: {s}\n", .{cipher_text});
    std.debug.print("Auth Tag: {s}\n", .{auth_tag});

    // 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.
    const bd_encrypted = try chilkat.BinData.init();
    defer bd_encrypted.deinit();
    bd_encrypted.appendEncoded(iv, "hex") catch {};
    bd_encrypted.appendEncoded(cipher_text, "base64") catch {};
    bd_encrypted.appendEncoded(auth_tag, "base64") catch {};

    const concatenated_gcm_output = try bd_encrypted.getEncoded(alloc, "base64");
    std.debug.print("Concatenated GCM Output: {s}\n", .{concatenated_gcm_output});

    // Sample output so far:

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

    const decrypt = try chilkat.Crypt2.init();
    defer decrypt.deinit();

    // 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.
    decrypt.setCryptAlgorithm("aes");
    decrypt.setCipherMode("gcm");
    decrypt.setKeyLength(256);
    decrypt.setEncodedKey(k, "hex");
    decrypt.setEncodedAad(aad, "hex") catch {};

    const bd_from_encryptor = try chilkat.BinData.init();
    defer bd_from_encryptor.deinit();
    bd_from_encryptor.appendEncoded(concatenated_gcm_output, "base64") catch {};

    const sz = bd_from_encryptor.getNumBytes();

    // Extract the parts.
    const extracted_iv = try bd_from_encryptor.getEncodedChunk(alloc, 0, 16, "hex");
    const extracted_cipher_text = try bd_from_encryptor.getEncodedChunk(alloc, 16, sz - 32, "base64");
    const expected_auth_tag = try bd_from_encryptor.getEncodedChunk(alloc, 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.
    try decrypt.setEncodedAuthTag(expected_auth_tag, "base64");

    // Also set the IV.
    decrypt.setEncodedIV(extracted_iv, "hex");

    // Decrypt..
    decrypt.setEncodingMode("base64");
    decrypt.setCharset("utf-8");
    const decrypted_text = decrypt.decryptStringENC(alloc, extracted_cipher_text) catch {
        // Failed.  The resultant authenticated tag did not equal the expected authentication tag.
        std.debug.print("{s}\n", .{try decrypt.getLastErrorText(alloc)});
        return;
    };

    std.debug.print("Decrypted: {s}\n", .{decrypted_text});
}