Version:

First Steps

This page will guide you through the process of setting up Keychain Core. Keychain Core is the library upon which all other components depend, and gives you the ability to develop your own Keychain-enabled applications using numerous APIs to suit your needs.

Installation

The easiest way to install Keychain Core is using our streamlined bootstrap script. This script automatically downloads and installs the latest versions of both the core C++ library and Python wrapper.

# Download and inspect the bootstrap script (recommended)
curl -LO https://keychain.jfrog.io/artifactory/keychain-core-prerelease-generic/keychain-core-installer-linux/get-core.sh
# cat get-core.sh  # Review the script before running
sh get-core.sh python

Alternative one-liner (inspect the URL first):

curl -sSL https://keychain.jfrog.io/artifactory/keychain-core-prerelease-generic/keychain-core-installer-linux/get-core.sh | sh -s -- python

The bootstrap script will: 1. Download the latest installer package from JFrog 2. Verify checksums automatically 3. Extract and run the installer 4. Install both the core C++ library and Python wrapper 5. Clean up temporary files

Installation Examples

User Installation (Recommended):

# Install to ~/.local (no sudo required)
sh get-core.sh --scope user python

System-Wide Installation:

# Install to /usr/local (requires sudo)
sudo sh get-core.sh --scope system python

Non-interactive Installation:

# Batch mode with no prompts
sh get-core.sh --non-interactive python

Verbose Output:

# Show detailed installation logs
VERBOSE=true sh get-core.sh python

What Gets Installed

After installation, you’ll have:

Core C++ Library: - libkeychain.so in ~/.local/lib/ (or /usr/local/lib/ for system install) - Header files in ~/.local/include/keychain/ and ~/.local/include/tkcrypt/ - Configuration skeleton in ~/.local/share/keychain/config/ - Documentation and examples in ~/.local/share/keychain/

Python Wrapper: - keychain_python package installed via pip - Automatic core library dependency resolution

Usage:

import keychain_python

# Use the library
print(f"Keychain Python version: {keychain_python.__version__}")

Prerequisites

Required Tools: - curl or wget (for downloading packages) - tar or unzip (for extracting packages) - sh compatible shell (bash, dash, zsh, etc.)

For Python Wrapper: - Python 3.7 or later - pip3

Manual Installation (Alternative)

If you prefer manual installation, you can download the installer package directly:

# Download installer package
curl -LO https://keychain.jfrog.io/artifactory/keychain-core-prerelease-generic/keychain-core-installer-linux/keychain-core-linux-installer-1.0.1+9010.tar.gz
curl -LO https://keychain.jfrog.io/artifactory/keychain-core-prerelease-generic/keychain-core-installer-linux/keychain-core-linux-installer-1.0.1+9010.tar.gz.sha256

# Verify and extract
sha256sum -c keychain-core-linux-installer-1.0.1+9010.tar.gz.sha256
tar -xzf keychain-core-linux-installer-1.0.1+9010.tar.gz
cd keychain-core-linux-installer-1.0.1+9010

# Run installer
./install --non-interactive python

Your First Keychain Application

Now that Keychain Core is installed, let’s create your first secure application. This example demonstrates the core concepts: creating a digital identity (persona), encrypting data for secure storage, and cryptographic signing for data integrity.

  • Python

  • C++

  • C

#!/usr/bin/env python3
"""
First Keychain Application - Secure encryption and signing with one persona
"""

import keychain_python
from keychain_python import Gateway, SecurityLevel, SerializedData

def main():
    # Initialize the gateway with default configuration
    settings = Gateway.init("~/.keychain/config/keychain.json")
    gateway = Gateway(settings)

    print("Creating secure persona...")

    # Create a persona (digital identity)
    my_persona = gateway.create_persona("MyName", "demo", SecurityLevel.MEDIUM)

    print("Encrypting data...")

    # Encrypt data for secure storage (self-encryption)
    secret_data = "This is my confidential information!"
    data = SerializedData(secret_data)
    encrypted = my_persona.encrypt(data, [])  # Empty recipients = encrypt for self

    print(f"Data encrypted successfully")
    print(f"Encrypted data type: {encrypted.data_type()}")

    print("Decrypting data...")

    # Decrypt the data
    decrypted = my_persona.decrypt(encrypted)
    recovered_data = decrypted.utf8_string()

    print(f"Recovered: '{recovered_data}'")

    print("Signing document...")

    # Sign a document for integrity verification
    document = "Important contract v1.0"
    doc_data = SerializedData(document)
    signed_doc = my_persona.sign(doc_data, True)

    print("Verifying signature...")

    # Verify the signature
    is_valid = gateway.verify(signed_doc)
    verified_content = signed_doc.utf8_string()

    print(f"Signature valid: {is_valid}")
    print(f"Document: '{verified_content}'")
    print("Secure operations successful!")

    # Cleanup
    Gateway.close()

if __name__ == "__main__":
    main()
/**
 * First Keychain Application - Secure encryption and signing with one persona
 */

#include <iostream>
#include <vector>
#include "keychain/gateway/gateway.hpp"
#include "keychain/cache/persona.hpp"

namespace kc = keychain;

int main() {
    try {
        // Initialize the gateway with default configuration
        kc::settings settings;
        kc::code result = kc::gateway::init(settings, "~/.keychain/config/keychain.json");
        if (result != kc::code::success) {
            std::cerr << "Failed to initialize gateway" << std::endl;
            return 1;
        }

        kc::gateway gateway(settings);

        std::cout << "Creating secure persona..." << std::endl;

        // Create a persona (digital identity)
        auto my_persona = gateway.create_persona("MyName", "demo", kc::security_level::medium);

        std::cout << "Encrypting data..." << std::endl;

        // Encrypt data for secure storage (self-encryption)
        std::string secret_data = "This is my confidential information!";
        kc::serialized_data data(secret_data);

        std::vector<kc::contact> recipients;  // Empty = encrypt for self
        auto encrypted = my_persona.encrypt(data, recipients);

        std::cout << "Data encrypted successfully" << std::endl;
        std::cout << "Encrypted data ready for storage" << std::endl;

        std::cout << "Decrypting data..." << std::endl;

        // Decrypt the data
        auto decrypted = my_persona.decrypt(encrypted);
        std::string recovered_data = decrypted.utf8_string();

        std::cout << "Recovered: '" << recovered_data << "'" << std::endl;

        std::cout << "Signing document..." << std::endl;

        // Sign a document for integrity verification
        std::string document = "Important contract v1.0";
        kc::serialized_data doc_data(document);
        auto signed_doc = my_persona.sign(doc_data, true);

        std::cout << "Verifying signature..." << std::endl;

        // Verify the signature
        bool is_valid = gateway.verify(signed_doc);
        std::string verified_content = signed_doc.utf8_string();

        std::cout << "Signature valid: " << (is_valid ? "true" : "false") << std::endl;
        std::cout << "Document: '" << verified_content << "'" << std::endl;
        std::cout << "Secure operations successful!" << std::endl;

        // Cleanup
        kc::gateway::close();

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
/**
 * First Keychain Application - Secure encryption and signing with one persona
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "keychain/gateway/gateway.h"
#include "keychain/cache/persona.h"

int main() {
    kc_settings_t* settings = NULL;
    kc_gateway_t* gateway = NULL;
    kc_persona_t* my_persona = NULL;
    kc_serialized_data_t* data = NULL;
    kc_encrypted_data_t* encrypted = NULL;
    kc_serialized_data_t* decrypted = NULL;
    kc_serialized_data_t* doc_data = NULL;
    kc_verifiable_data_t* signed_doc = NULL;

    printf("Initializing Keychain...\n");

    // Initialize the gateway
    const char* config_path = "~/.keychain/config/keychain.json";
    if (kc_gateway_init(&settings, config_path, strlen(config_path)) != KC_SUCCESS) {
        fprintf(stderr, "Failed to initialize gateway settings\n");
        return 1;
    }

    if (kc_gateway_construct(&gateway, settings) != KC_SUCCESS) {
        fprintf(stderr, "Failed to construct gateway\n");
        return 1;
    }

    printf("Creating secure persona...\n");

    // Create persona
    if (kc_gateway_create_persona(gateway, &my_persona, "MyName", 6, "demo", 4,
                                 KC_SECURITY_LEVEL_MEDIUM, true) != KC_SUCCESS) {
        fprintf(stderr, "Failed to create persona\n");
        goto cleanup;
    }

    printf("Encrypting data...\n");

    // Create serialized data from secret
    const char* secret_data = "This is my confidential information!";
    if (kc_serialized_data_construct_from_utf8(&data, secret_data, strlen(secret_data)) != KC_SUCCESS) {
        fprintf(stderr, "Failed to create serialized data\n");
        goto cleanup;
    }

    // Encrypt for self (no recipients)
    if (kc_gateway_encrypt(gateway, &encrypted, my_persona, data, NULL, 0) != KC_SUCCESS) {
        fprintf(stderr, "Failed to encrypt data\n");
        goto cleanup;
    }

    printf("Data encrypted successfully\n");
    printf("Decrypting data...\n");

    // Decrypt the data
    if (kc_gateway_decrypt(gateway, &decrypted, my_persona, encrypted) != KC_SUCCESS) {
        fprintf(stderr, "Failed to decrypt data\n");
        goto cleanup;
    }

    // Extract the decrypted data
    char* recovered_data = kc_serialized_data_utf8_string(decrypted);
    printf("Recovered: '%s'\n", recovered_data);

    printf("Signing document...\n");

    // Create document data
    const char* document = "Important contract v1.0";
    if (kc_serialized_data_construct_from_utf8(&doc_data, document, strlen(document)) != KC_SUCCESS) {
        fprintf(stderr, "Failed to create document data\n");
        free(recovered_data);
        goto cleanup;
    }

    // Sign the document
    if (kc_gateway_sign(gateway, &signed_doc, my_persona, doc_data, true, NULL, 0, NULL, 0) != KC_SUCCESS) {
        fprintf(stderr, "Failed to sign document\n");
        free(recovered_data);
        goto cleanup;
    }

    printf("Verifying signature...\n");

    // Verify the signature
    bool is_valid = (kc_gateway_verify(gateway, signed_doc) == KC_SUCCESS);
    char* verified_content = kc_verifiable_data_utf8_string(signed_doc);

    printf("Signature valid: %s\n", is_valid ? "true" : "false");
    printf("Document: '%s'\n", verified_content);
    printf("Secure operations successful!\n");

    // Free strings
    free(recovered_data);
    free(verified_content);

cleanup:
    // Cleanup resources
    if (signed_doc) kc_verifiable_data_destruct(&signed_doc);
    if (doc_data) kc_serialized_data_destruct(&doc_data);
    if (decrypted) kc_serialized_data_destruct(&decrypted);
    if (encrypted) kc_encrypted_data_destruct(&encrypted);
    if (data) kc_serialized_data_destruct(&data);
    if (my_persona) kc_persona_destruct(&my_persona);
    if (gateway) kc_gateway_destruct(&gateway);
    if (settings) kc_settings_destruct(&settings);

    kc_gateway_close();

    return 0;
}
Expected Output
Creating secure persona...
Encrypting data...
Data encrypted successfully
Encrypted data type: ENCRYPTED_DATA
Decrypting data...
Recovered: 'This is my confidential information!'
Signing document...
Verifying signature...
Signature valid: true
Document: 'Important contract v1.0'
Secure operations successful!

What Just Happened?

This example demonstrates the core Keychain concepts with immediate results:

  1. Gateway Initialization: The gateway manages all cryptographic operations and configuration

  2. Single Persona Creation: Create one digital identity with hardware-secured keys - no wait time

  3. Self-Encryption: Encrypt data for secure storage - instant encryption/decryption

  4. Digital Signing: Sign documents for integrity verification - immediate signature/verification

  5. Local Operations: All operations work locally without requiring network communication

Key Security Features
  • Hardware-Secured Keys: Private keys are generated and stored in secure hardware

  • Instant Results: Self-encryption and signing work immediately without PKI delays

  • Data Integrity: Cryptographic proof that data hasn’t been tampered with

  • Secure Storage: Encrypted data can be safely stored or transmitted

Perfect for Getting Started
  • No network dependencies - everything works offline

  • No waiting - immediate cryptographic operations

  • Positive experience - successful results every time

  • Real security - hardware-backed cryptographic protection

Next Steps - Solution Accelerators

We recommend that you get familiar with the Keychain capabilities by downloading, building, and trying one or more of our solution accelerators.

These accelerators illustrate simple use cases and highlight usage patterns of Keychain Core in multiple programming languages and environments (primarily Java and Python on Linux, Android Java, and C#.NET on Windows).

These sample projects are provided as-is, solely for informational/educational purposes and do not represent production-level code.