Direct Key Usage

This page describes how to add to operate over keys directly, creating and fetching them, and then using them to encrypt. In many applications, it is better to leverage the easy-to-use functional capabilities in the Ionic SDK instead of directly manipulating keys and ciphertext.

The examples in this page presume that you have completed the Getting Started Guide for some platform and language. Now that you’ve gotten the basic sample app running, you can alter the code to change functionality.

The Ionic SDK supports a number of ciphers (see the Ionic SDK documentation for the full list).
The following sample code first creates a new key, and then uses the SDK’s functions for AES-CTR mode to perform encryption and decryption using this key.

C++

In the sample code we use the ISCryptoAesCtrCipher class provided by the SDK for our AES-CTR encryption and decryption.

First, here is a code sample that encrypts a string:

#include <stdio.h>
#include <ISAgent.h>

int main()
{
    std::string input;

    std::cout << "Enter string to encrypt:";
    std::getline (std::cin, input);

    // Setup an agent object to talk to Ionic
    ISAgent agent;
    agent.initialize();

    //Forming the key request object
    ISAgentCreateKeysRequest keyRequest;
    ISAgentCreateKeysRequest::Key requestKey("RequestKey", 1);
    ISAgentCreateKeysResponse keyResponse;
    ISAgentCreateKeysResponse::Key responseKey;

    //Requesting a new key from Ionic
    keyRequest.getKeys().push_back(requestKey);
    agent.createKeys(keyRequest, keyResponse);
    responseKey = keyResponse.getKeys().front();

    //Selecting a Crypto cipher, here we have chosen AES-CTR mode
    ISCryptoAesCtrCipher crypto;
    ISCryptoBytes cipherBytes;

    //Set key and encrypt
    crypto.setKey(responseKey.getKey());
    crypto.encrypt(input, cipherBytes);

    std::string encryptedString;
    ISCryptoUtils::binToBase64(cipherBytes, encryptedString);

    std::cout << "KeyTag: " << responseKey.getId() << std::endl;
    std::cout << "Encrypted String: " << encryptedString << std::endl;

    return 0;
}

Now, if you have an encrypted string and a keytag that is associated with it, you can request the key and manually decrypt it:

#include <stdio.h>
#include <ISAgent.h>

int main()
{
    std::string keyTag;
    std::string encryptedString;
    // Request a KeyTag for example, "ABcd4H7hrWg"
    std::cout << "Enter the KeyTag:"; 
    std::getline (std::cin, keyTag);
    // Request an encrypted string example, "GmkvWG2UMYo5YSQk9jpQph22rwVzdQqoy3cPbCHtJ0uXE/SykS66HQ=="
    std::cout << "Enter encrypted string to decrypt:"; 
    std::getline (std::cin, encryptedString);

    // Setup an agent object to talk to Ionic
    ISAgent agent;
    agent.initialize();

    // Form the key request object:
    ISAgentGetKeysRequest keyRequest;
    ISAgentGetKeysResponse keyResponse;
    ISAgentGetKeysResponse::Key responseKey;

    // Add keytag to the list of keys we want, and request them:
    keyRequest.getKeyIds().push_back(keyTag);
    agent.getKeys(keyRequest, keyResponse);

    for (int i=0; i<keyResponse.getKeys().size(); i++)
    {
        responseKey = keyResponse.getKeys()[i];

        ISCryptoAesCtrCipher crypto;
        ISCryptoBytes cipherBytes;
        crypto.setKey(responseKey.getKey());

        ISCryptoUtils::Base64ToBin(encryptedString, cipherBytes);
        std::string clearText;
        crypto.decrypt(cipherBytes, clearText);
        std::cout << "Decrypted: "<< clearText << std::endl;
    }
    return 0;
}
NOTE: This code sample can be found on Github at https://github.com/IonicDev/samples/blob/master/cpp/direct-keys/src/IonicDirectKeys.cpp.

Java

In this sample code, we create keys and then retrieve them to show how we can directly request keys as an application developer. Typically you should instead use the ChunkCrypto or FileCrypto convenience wrappers.

Java 2.x SDK:

NOTE: This code sample can be found on Github at https://github.com/IonicDev/samples/blob/master/java/direct-keys/src/main/java/com/ionic/direct-keys/IonicDirectKeys.java.

First we create two keys marked with an attribute named “classification” with a value of “restricted”:

CreateKeysRequest request = new CreateKeysRequest();

// Here update request.getKeys() as the list of what it should create.
// We are going to add a key attribute "classification", with the single value of "restricted"
KeyAttributesMap attributes = new KeyAttributesMap();
List<String> values = new ArrayList<String>();

// NOTE: Make sure you have access to data tagged with "restricted" or you will not be able to fetch this key:
values.add("restricted");
attributes.set("classification", values);
CreateKeysRequest.Key requestKey = new CreateKeysRequest.Key("example", 2, attributes);
request.getKeys().add(requestKey);

// Now ask the server to make those keys:
CreateKeysResponse response;
try {
    response = agent.createKeys(request);
} catch (SdkException ex) {
    System.out.println("Sdk Exception: " + ex.getMessage());
    return;
}

List<CreateKeysResponse.Key> keys = response.getKeys();

// Show us what keys we got (you can always get a key right when you create it):
List<String> createdKeyIds = new ArrayList<String>();
for (CreateKeysResponse.Key key : keys) {
    System.out.println("We created a key with the Key Tag: " + key.getId());
    createdKeyIds.add(key.getId()); //keep a list of IDs so we can request them later
}

Then, we can fetch these (or other) keys as follows. This assumes that the above code built the list createdKeyIds for us to use here. Typically, these key IDs would be obtained from an alternative route, such as a column in a database or a header on the data.

GetKeysRequest keysRequest = new GetKeysRequest();
keysRequest.getKeyIds().addAll(createdKeyIds);
GetKeysResponse keysResponse = null;
try {
    keysResponse = agent.getKeys(keysRequest);
} catch (SdkException ex) {
    System.out.println("Sdk Exception: " + ex.getMessage());
    System.exit(1);
}

// Show what we got access to after a request for keys:
for (GetKeysResponse.Key key: keysResponse.getKeys()) {
    System.out.println("We fetched a key with the Key Tag: " + key.getId());
}

Java 1.x SDK:

The core code is the same between the SDK versions, but a sample which builds with the Java 1.x SDKs can be found on our Github below.

NOTE: This code sample can be found on Github at https://github.com/IonicDev/samples/blob/master/java-jni/direct-keys/src/main/java/com/ionic/direct-keys/IonicDirectKeys.java.

C#

In the sample code we use the AesCtrCipher class provided by the SDK to perform our encryption and decryption.

First, here is a code sample that encrypts a string:

using System;
using IonicSecurity.SDK;

namespace Raw_Encryption
{
    class Program
    {
        static private Agent agent = null;
        static private AesCtrCipher cipher = null;

        static void Main(string[] args)
        {

            Crypto.Initialize();

            // Setup an agent object to talk to Ionic
            AgentConfig config = new AgentConfig();
            agent = new Agent();
            agent.Initialize(config);

            //Selecting a Crypto cipher, here we have chosen AES-CTR mode
            cipher = new AesCtrCipher();

            CreateKeysRequest request = new CreateKeysRequest();
            CreateKeysRequest.Key requestKey = new CreateKeysRequest.Key("reference_key");

            request.Keys.Add(requestKey);

            CreateKeysResponse response = agent.CreateKeys(request);
            List<CreateKeysResponse.Key> responseKeys = response.Keys;

            cipher.KeyBytes = responseKeys[0].Bytes;
            string keyId = responseKeys[0].Id;

            string stringClearText = "Hello Ionic!";
            string encryptedString = null;

            cipher.EncryptToBase64(stringClearText, ref encryptedString);

            output_to_console(keyId, encryptedString);
        }

        static private void output_to_console(string keyId, string encryptedString)
        {
            Console.WriteLine("Encryption KeyTag:  " + keyId);
            Console.WriteLine("Encrypted String:  " + encryptedString);
            Console.ReadKey();
        }
    }
}

Now, if you have an encrypted string and a keytag that is associated with it, you can request the key and manually decrypt it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using IonicSecurity.SDK;

namespace Raw_Decryption
{
   class Program
   {
       static private Agent agent = null;
       static private AesCtrCipher cipher = null;

       static void Main(string[] args)
       {

           Console.Write("Enter the KeyTag: ");
           string keyTag = Console.ReadLine();
           Console.Write("Enter the encrypted string to decrypt: ");
           string encryptedString = Console.ReadLine();

           Crypto.Initialize();

           AgentConfig config = new AgentConfig();
           agent = new Agent();
           agent.Initialize(config);

           GetKeysRequest request = new GetKeysRequest();
           request.KeyIds.Add(keyTag);
           GetKeysResponse response = agent.GetKeys(request);

           cipher = new AesCtrCipher();
           cipher.KeyBytes = response.Keys[0].KeyBytes;

           string decryptedString = null;
           cipher.DecryptFromBase64(encryptedString, ref decryptedString);

           // Helper function for printing to the console see below
           output_to_console(keyTag, encryptedString, decryptedString);
       }

       static private void output_to_console(string keyTag, string encryptedString, string decryptedString)
       {
           Console.WriteLine("This is an example console application to decrypt strings with the Ionic SDK\n");
           Console.WriteLine("Encryption KeyId: " + keyTag);
           Console.WriteLine("Encrypted String: " + encryptedString);
           Console.WriteLine("Decrypted String: " + decryptedString);
           Console.WriteLine("\nPress Enter to continue...\n");
           Console.ReadKey();
       }
   }
}
NOTE: This code sample can be found on Github at https://github.com/IonicDev/samples/blob/master/csharp/direct-keys/DirectKeys.cs.

Python

You may use agent.createkey or agent.createkeys to request keys, and agent.getkey or agent.getkeys to operate directly on keys.

You can then use those keys with Ionic provided encryption libraries, or any other use needed. In the sample code we use the AesCtrCipher class provided by the SDK for our AES-CTR encryption.

import ionicsdk
import binascii

agent = ionicsdk.Agent()

try:
    createdKey = agent.createkey()
except ionicsdk.exceptions.IonicException as e:
    print("Error creating a key: {0}".format(e.message))
    sys.exit(-2)

cipher = ionicsdk.AesCtrCipher(createdKey.bytes)
encryptedstring = cipher.encryptstr("Hello AES Cipher!")

# Print out the ciphertext as hex
print("Encryption KeyId: " + createdKey.id)
print("Encrypted String: " + binascii.hexlify(encryptedstring))
NOTE: This code sample can be found on Github at https://github.com/IonicDev/samples/blob/master/python/direct-keys/directkeys.py.