Chapter 1: Introduction

Alliance Key Manager implements a wire protocol for encryption key retrieval. This means that any client application that is capable of creating a TLS connection to the key server, and which has the proper X509 certificates, can retrieve encryption keys from the key server. The Python language does provide this type of support and Python developers can easily retrieve 128-bit, 192-bit, and 256-bit encryption keys for use with the AES encryption algorithm.

Change log

The following table provides information on the changes to this documentation:

Version Date Description
2.1.0.001 10/20/2011 Initial release.
2.1.0.002 3/14/2014 Manual format updates.

Chapter 2: Key Retrieval API Documentation

The Alliance Key Retrieval Interface Reference manual provides a full description of the key retrieval interface. Please refer to this manual for more information about key retrieval fields and options. The sample code below provides a quick view of a sample key retrieval application. Note that in the Python sample code below the key instance name is set to blanks to indicate the default instance of the key. If you are decrypting you will probably want to specify the actual key instance name to use.

Chapter 3: Certificates

In order to make a TLS connection to the Alliance Key Manager server there must be two PEM files in a local directory. The client PEM file contains the client X509 certificate and private key (cat the two PEM files together), and the Certificate Authority file contains the CA certificate from the key server. You should protect these files with native Linux/Unix security.

Chapter 4: Sample Python Code

The following code example shows a simple method of retrieving an encryption key from the Alliance Key Manager server. You should modify this code for use in your environment.

import socket
import ssl
import sys

def dump_https_page(hostname, uri='/'):

  sock = socket.socket(socket.AF_INET)
  s = ssl.SSLSocket(sock=sock,
                    ca_certs='/etc/ssl/certs',
                    server_hostname=hostname)
  print 'have socket'
  s.connect((hostname, 443))
  print 'connected'

  print >>s, 'GET %s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n' % (
      uri, hostname),

  t = s.read()
  while t:
    print t,
    t = s.read()

Below are examples of loading cryptoID and X.509 certificate chains:

#Load cryptoID certChain and privateKey.  Requires cryptoIDlib.
from cryptoIDlib.CertChain import CertChain
s = open("./test/clientCryptoIDChain.xml").read()
certChain = CertChain()
certChain.parse(s)
s = open("./test/clientCryptoIDKey.xml").read()
privateKey = parseXMLKey(s, private=True)

#Load X.509 certChain and privateKey.
s = open("./test/clientX509Cert.pem").read()
x509 = X509()
x509.parse(s)
certChain = X509CertChain([x509])
s = open("./test/clientX509Key.pem").read()
privateKey = parsePEMKey(s, private=True)

Sample Python code for key retrieval and encryption with PyCrypto:

#!/usr/bin/env python

from Crypto.Cipher import AES
import base64
import os

# the block size for the cipher object; must be 16, 24, or 32 for AES
# A block size of 16 is required for NIST FIPS-197 compatibility.
BLOCK_SIZE = 16

# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length.  This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'

# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING

# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)

# retrieve the encryption key from the Alliance Key Manager server


# create a cipher object using the random secret
cipher = AES.new(secret)

# encode a string
encoded = EncodeAES(cipher, 'password')
print 'Encrypted string:', encoded

# decode the encoded string
decoded = DecodeAES(cipher, encoded)
print 'Decrypted string:', decoded