Sunday, February 8, 2009

“Managed Keys” as an open source project

MOTIVATION

While working on a client-server project at my employer, the client software we were building in-house needed appropriate standards compliant Server software. The technology being built is to enable specific industry standards.

Our original plan was to rely on third-parties to supply the server side software. However, we quickly found out these companies were either going bankrupt or had unreliable support. Even if you are willing to pay an additional cost, these variations were occasionally throwing a monkey wrench into our project schedules.

MAKING A BUSINESS CASE

Realizing that this requires a long-term solution, I proposed that we build the server software in-house. My manager was not jumping with joy at the idea. He knows that endorsing this takes a commitment of resources on his part. Besides, he remembered to point out, there were already people working on that side of the equation.

However, at close examination the server software being built appeared to be patch jobs on previously built server software. They sometimes cost avoidable delays, as spurious bugs showed up and was costing time and money to debug and fix.

This got me thinking in terms of creating an open source project. My employer was neutral on the idea, as they knew it can be useful. However, they were too busy to weigh in on the effort and project its potential impact on the longer-term success of the client-server project.

So far, we discussed making a business case for the open source project. Now, you might have a legitimate question as to what in the world does this client-server software do?

WHAT CAN BE OPEN SOURCED?

Revealing projects that are not in the public domain will certainly irk my employer and that cannot be my intent, either. After some careful thought , I came to a resolution.

The server software in question requires software building blocks that can be widely applied to a variety of use cases. This blog will analyze and design these software building blocks in great detail.

SOFTWARE BUILDING BLOCKS

How to Secure your data?

The need to maintain confidential data in ecommerce applications and databases is not a new requirement. The following use case diagram paints a partial picture of some of the applications that have a need to protect sensitive data,



However, the art of protecting data can do with the availability of well thought out security frameworks, such as this one, presented by Kevin Kenan's work on "Cryptography in the Database - The Last Line of Defense".

If you scour the industry for such standard frameworks, it is hard to find an open source robust solution that you can build upon.

The apparent lack of security building blocks for safe and simple use of cryptography in applications has invoked a response from industry heavy weight google, as they cameout with a Toolkit known as keyzcar.

However, as we'll see here, these solutions generally tend to fall short in their support for a comprehensive Key Management strategy, as outlined by Symantec's Kevin Kenan in his well-written book.


Hands-on with Google's Cryptographic Toolkit



Providing a brief and efficient introduction to google's safe cryptographic library here, Keyczar: A Cryptographic Toolkit are the authors of the toolkit, Arkajit Dey and Stephen Weis.

You may also read about a hands-on approach that puts the toolkit through a few basic use cases.

Managed Keys



JUSTIFY THE PROJECT (ANALYSIS)


The lack of free and open source security building blocks to support use cases such as information assurance in an enterprise, or to monitize digital content, is a motivation for the "Managed Keys" project. Business databases need to be protected and digital data needs security.

While google's keyzcar and similar toolkits such as openssl are available for applications to perform cryptographic operations, the management of cryptographic keys used in these operations is a problem left for the applications to handle.

This is a non-trivial excersise for an application to handle on its own. If it does, the application must either dedicate its own resources to do so or the application's risks compromising on an effective content protection.

There is ample evidence from reading symantech's Kevin Kenan's "... last line of defense" book, you need an effective "Key Management Systems" as part of your enterprise information assurance infrastructure.

REQUIREMENTS BASELINE


The high-level functional requirements for our key management system is baselined as follows,

Purposeful Generation


1. Each generated key shall be assigned an application purpose tag that shall be used for selecting the key on a cryptographic application request.

Key Types


2. The key types supported include symmetric and asymmetric keys.
3. The default length for symmetric keys shall be 128 bits.
4. The default length for asymmetric keys is 1024 bits.
5. Key Lengths for symmetric keys shall be a subset of { 128, 256 }
6. Key Lengths for Asymmetric keys shall be a subset of { 1024, 2048}

Key Formatting


7. Keys shall be formatted as JASON strings for export.

Key Integrity and Protection


8. Keys shall have their HMAC values computed on their generation and stored and made available to assure integrity.
9. Keys shall be optionally encrypted themselves while at Rest in the Key Store.

Life Cycle


10. The life of a Key shall start with a status of "Pending" on birth and goes through "Live", "Retired" and finally the "Expired" stage collectively known as a key Life cycle.

Key Storage


11. Key store access interface shall remain independent of the specific storage used.
12. Key backup shall be available.

Access Control


13. Access to Key store shall be provided only to registered users.
14. All registered users shall have read-only access privileges to the Keys in the key store.
15. Administrative users shall have privileges to generate New Keys, modify and remove them.

PLANNING THE ARCHITECTURE




Tuesday, October 28, 2008

Key Vault Concept Application

Sometimes back came across a Google published Toolkit that aimed at safe and simple use of cryptography in their applications. That inspired this project namely, a key vault.

APPLICATION: KEY VAULT

This project also has relevance to an earlier discussion in an adjacent blog, studying the various building blocks of a DRM Server.

The following figure outlines what could be a high-level overview of modules present in a typical key management System.



KEY VAULT - STATEMENT OF THE PROBLEM

Enterprise applications store sensitive information in databases & there are Media applications that produce and manage content of considerable dolor value. A common problem faced by these applications is that they require a key vault to store and manage the cryptographic keys used for content protection.
Usage Scenarios

Expanding on the above problem statement,this link elaborates on the kind of users and usage models that we want our Key Vault application to satisy.


REQUIREMENTS

This section establishes some of the high-level goals of the key vault application. The scope is established by the requirements stated here for our application.

INTRODUCTION

"It's all talk until the code runs."— Ward Cunningham

In this section, we describe a rudimentery framework for a key management sub-system. The design we will consider is flexible enough to make use of any available crypto library as its engine. However, this discussion is based on a crypto library from google, namely keyczar.. The above KMS framework gets its roots from Kevin Kenan's work on "Cryptography in the Database - The Last Line of Defense". Readers are welcome to share your thoughts experiences on this subject in the comments section of this blog.


Consumer Interface:


This is an Application facing software interface and can be configured to use different keysets depending on the type of data. For e.g., if you are encrypting an XML snippet that is part of a larger message, you can configure the consumer to use a specific set of keys for this purpose.



...

try {

KeyConsumer kc = new KeyConsumer(); // API

// set Data identity, selects keyset to use for Crypto ops. userData udata = new userData(dataIdentity.IDMSG_ENC_A);

// setup the raw data in user object
udata.put( new String("Secret Message") );

// invoke crypto operation
kc.encrypt(udata);

System.out.println(udata.get());

// invoke another crypto operation
kc.decrypt(udata);

System.out.println(udata.get());
}
catch(Exception ex){
ex.printStackTrace();
}





Provider Interface:


A provider abstracts the consumer from the specifics of an engine used to perform the crypto operations. Provider uses the crypto engine to complete the requested operation and returns a receipt to the consumer. The receipt contains the resultant data and certain identification information. This level of abstraction allows us to plug-in different engines and key vaults, where it is desirable.


Key Manifest Interface:


The Key Manifest bridges the key aliases used by consumer to the actual keysetIds in the key vault. It also has the important function of managing Key Life Cycles.


Key Engine Interface:


This interface is used by the provider to satisy all the crypto operation requests from the consumer. Access to this module should be access restricted. The key engine reads the keysets from the key vault and transforms the user data.

In this implementation, we make use of keyczar, which uses a file system based key vault. The keyczar library is adopted to read the keys from a database instead.


Key Vault Interface:


The Key Vault stores all the keys used in the applications cryptographic operations. Hence, it must be access restricted. The IKeyVault interface, typically provides opertations to add/remove/update/read keys from the key vault.

Key Vault is utilized by the Engine and the Key Manager components.


Key Manager Interface:


This interface performs the administration of the keys as well as the configuration of the key vault and the key manifest. It is access restricted to cryptographic officers.

Friday, October 24, 2008

Hands-on Keyczar cryptographic Toolkit

In this brief article, we examine a cryptographic Toolkit from google known as keyczar. The stated aim of the toolkit is to simplify some of the choices made by application developers while using cryptograpic operations in their applications. Here, we will take a hands-on approach and put the toolkit through a few basic use cases.

Applying cryptography - a few basic use cases

The following figure provides us with a few basic use cases of interest. As our first task, we consider encrypting a small string and then performing the reverse operation, which is decryption and getting back the original message.



Encrypting and Decrypting a String

The idea is to use the toolkit to scramble a small piece of data such as "Secret Message" in two different ways. As a first choice, we need a cipher that is quite fast. Then we'll use a cipher that has other advantages, but isn't necessarily as fast. The two chosen algorithms of interest are,

A. A cipher known as AES, the expansion of which goes like, Advanced Encryption Standard. This is a quite fast and powerful algorithm.

B. A cipher known as RSA, the expansion of which will lead to the initials of its inventors. This cipher has an interesting property that is equivalent to, an ability to lock your door with one key and then open it with a totally different key that looks nothing like the original key.

The following diagram is an illustration of the above two operations to be performed.



Brief look at keyczar's developer interfaces

Keyczar is a relatively newer library in the world of libraries like OpenSSL, BSAFE etc. The stated aim is to clearly provide a simpler alternative in certain scenarios for web and other application developers.

Examining the toolkit, it comes with about 36 java classes collected in a .JAR container. In addition, there is a command line support to invoke the library using a tool interface called as Keyczartool.

Interfacing with the Keyczartool

The first thing to figure out is how to invoke this command line interface. The documentation, while quite good, doesn't tell you how to get a handle to this tool. If you examine the class library, you suddenly realize, you have direct access to this command line interface from your java program. We will see it here,




import org.keyczar.*; // package; import the jar into your project.

// get a handle to the command line interface.
KeyczarTool kt = new KeyczarTool();

try {

// creates a keystore ( a dir. that'll hold some flat files )

String kargsCreate[] =
{"create", "--location=c:\\keyczarStore", "--purpose=crypt", "--name=Test"};

kt.main(kargsCreate);

}
catch(Exception ex){
// do your logging/handling
}


Specifying the Key Store

If you examine the above code, you'll notice that,

A.) We have specified a base directory where we want the library to place all our keysets. This happens to be c:\keyczarStore. You must have this directory created on your filesystem for this command to work.

B.) KeyStore: Notice the command line syntax that is used here. This is reasonably well-documented in the wiki or a PDF documentation from the keyczar site.



As you execute the above command, you'll see the library creates a file named "meta" or "somethingmeta" in your keysotre directory. If you examine the contents of this directory, it starts with something like this,


{"name":"Test","purpose":"DECRYPT_AND_ENCRYPT","type":"AES","versions":
...}


The name of the keystore is "Test", which is set by us. This store is meant to store keys that we add for use with the symmetric cipher, AES. There is some versioning information as well.

Adding Keys to our Key Store.

Our plan is to call the library to encrypt a common string, "Secret Message". We'll then print this scrambled message. Then we can call the library to decrypt
it back to the original string.

Now, in order to do this, we need to add some keys to the key store. These keys can be then used for these scrambling and descrambling operations we plan to do. The following snippet of code accomplishes this task and adds some keys to our key store.




try {

// creates a primary key of default size & store into our key store

String kargsaddKey[] = {"addkey", "--location=c:\\keyczarStore", "--status=primary"};

kt.main(kargsaddKey);


}
catch(Exception ex){
// do your logging/handling
}


// creates an additional active key
try {

String kargsaddKey2[] = {"addkey", "--location=c:\\keyczarStore"};

kt.main(kargsaddKey2);

}
catch(Exception ex){
}



Notice, we have changed the verb from "create" used earlier to "addkey", in the parameters passed into the command line API.

If you are curious and examine your keystore location, you'll notice a couple of more key files added. The contents of these key files will naturally look like key material. You can see a sample below...


{"aesKeyString":"j1U6ReVCwtpYYbWBk4CrTA","hmacKey":{"hmacKeyString":"i77bcM9EIqPSnOHxgonOjFaDL7gQnR8YpMvF0-RVT_Y","size":256},"mode":"CBC","size":128}



There are a few points to note here,

1. The keys that are in a printable form are base64 transformed.

2. Notice the term CBC. This expands to cipher block chaining mode. This is the key mixing mode used here. This mode is quite easy to use on small blocks of data. Perhaps the design goal here is to support enciphering/decipher of relatively small messages and that might have influenced this selection. When used with larger blocks, this mode has a disadvantage in that, the encryption has to proceed serially.

3. Finally, we also see a hmacKey being stored. This is an integrity checking solution, by which the keystore tracks the keys, so they are not compromised.

A final point here. The keys that are stored here may themselves need to be encrypted. This may prevent someone unauthorized from gaining easy access to them. The library has a way to accomplish this. We won't go into that here.

Applying the cipher and back

The following block of code simply applies the keys fetched from the keystore. Notice the keys that are used is based on the directory identification.



// Encrypting the plaintext
Encrypter encrypter = new Encrypter("c:\\keyczarStore");
String ciphertext = encrypter.encrypt("Secret message");
System.out.println(ciphertext);

// decrypting the scrambled message
Crypter crypter = new Crypter("c:\\keyczarStore");
String plaintext = crypter.decrypt(ciphertext);
System.out.println(plaintext);




Applying the asymmetric RSA cipher

Notice the commandline syntax variations here to specify the asymmetric cipher,




KeyczarTool kt2 = new KeyczarTool();

// create a private key of default size
try {

String kargscreateKey[] = {"create", "--location=C:\\keyczarStore\\rsakeys", "--purpose=crypt", "--asymmetric=rsa"};

kt2.main(kargscreateKey);

}
catch(Exception ex){
}

// creates a private key
try {

String kargsaddKey[] = {"addkey", "--location=C:\\keyczarStore\\rsakeys", "--status=primary"};

kt2.main(kargsaddKey);
}
catch(Exception ex){
}

// creates a public key
try {

String kargsaddKey[] = {"pubkey", "--location=C:\\keyczarStore\\rsakeys", "--destination=C:\\keyczarStore\\rsakeys\\rsa-publickeys"};
kt2.main(kargsaddKey);
}
catch(Exception ex){
}




Now we make use of the keys from the asymmetric key store and encipher and decipher a message,




// Initialize an Encrypter with the public keys
Encrypter encrypterpki = new Encrypter("C:\\keyczarStore\\rsakeys");
String ciphertextpki = encrypterpki.encrypt("Secret Message");
System.out.println(ciphertextpki);

// Initialize a Crypter with the private keys
Crypter crypterpki = new Crypter("C:\\keyczarStore\\rsakeys");
String plaintextpki = crypterpki.decrypt(ciphertextpki);
System.out.println(plaintextpki);




Conclusions
We only scratched the surface here. Perhaps, there is more to come. There are a few observations here,

1. The library and the API is easily accessible from a java program.
2. The commandline mode presents a set of default choices, which helps to simplify the usage.