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.

No comments: