JDK1.5 contains many cool new features. One part that holds dear to my heart and to the work that I do are all the new enhancements to the Security architecture. There has been alot of major work going on and Sun has to be congratulated.
First I’ll outline the major new features:
- JSSE has several new features:
- Now supports non blocking SocketChannels, which is good news for the new generation of non blocking servlet engines that are coming up.
- Kerberos ciphersuites
- Default trustmanager now uses PKIX
- Now allows use of 3rd party JSSE Providers
- Support for Hardware encrypton accellerators and smart cards through PKCS#11 (Very Cool!!!)
- Support for Elliptic Curve Cryptography (ECC) (BouncyCastle had that before, must verify that Sun used their conventions). Note though that the included SunJCE provider does not support ECC, so you must look elsewhere
- Better support for both PKCS#8 and PKCS#12 which should be good for interop with say OpenSSL and various browsers.
I’ll now explore in detail some of these features:
PKCS#11
Better Performance
In my opinion this is the single most important new feature of JCE1.5. Why? This allows us to utilize our existing Java code together with much improved speed, often in the order of magnitude. For example with this and the new non blocking support in JSSE, we can create secure web applications far more powerful and faster than other platforms such as .NET, Perl, Python or even Apache Modules in C.
Almost all the crypto api’s for other platforms are based on either OpenSSL or Microsoft’s Crypto API. This meant that applications using crypto written in Perl or Python, where often faster than the equivalent Java applications.
A good example of what is possible is that the Solaris 10 version of JDK1.5 is configured to use the PKCS#11 support of their Solaris Cryptographic Framework by default. This means in worst case you have native code running the crypto and in best case full support of hardware crypto/ssl accellerators, offering orders of magnitued better performance.
Increased Security
Some crypto accellerators support their own secure keystore. Most notable is nCipher as well as the not too fast, yet very secure crypto smartcards. These devices allow you to create PrivateKeys directly using their built in hardware and store the resulting keypair onboard. It never actually leaves the device. Thus they bad boys will have a very hard time getting hold of it. For example you wont be able to scan through memory or disk for the private key. Smartcards are good for personal signing in applications such as my NeuClear framework, while nCipher is particularly good for just about any serverside crypto use.
I implemented a set of interfaces for the same purpose as part of the crypto libraries in NeuClear.org, which I still think is more elegant than the JCE approach. However the new JCE support will make it easier to create implementations using the NeuClear library. My approach is to keep it simple for the application developer. It takes a simple interface Signer which provides 4 simple methods. The most important is sign(String name, byte data[]) which just takes an alias and the data to be signed. The implementation of the Signer figures out how to initialize the Cipher, how to get the passphrase (perhaps by asking for a passphrase) etc. It then returns the signed data:
// Creates a signer, which uses the JCE and a GUI dialog for asking the passphrases.
Signer signer=new JCESigner("mykeys.jks","jks","SUN",new GUIDialogAgent());
byte[] raw =signer.sign("My Alias",data);
The JCE approach is a bit more complicated, but not bad:
// The new KeyStore.Builder class for dynamically getting the keys from the token
KeyStore.Builder builder = new KeyStore.Builder("PKCS11");
// Add CallBackHandler to handle passphrase requests
builder.setCallbackHandler(new MyGuiCallbackHandler());
KeyStore ks = builder.getKeyStore();
// We pass a null passphrase as the CallBackHandler asks us for it
Key key = ks.get(alias, null);
Signature sig=Signature.getInstance("SHA1withRSA");
sig.initSign(key);
sig.update(data); //Add some data
byte[] raw = sig.sign(); // Creates signature
The interesting thing iabout the JCE PKCS#11 approach is that they PrivateKey’s returned by ks.get() do not necessarily contain the real key data. They may very well just be a reference to the real key on the hardware device.
I designed my above Signer interface with the intent of adding support in the future for hardware devices such as nCipher and Smartcards. It is very cool that this task has been made much easier now.
PKCS#11 Implementations
Physically the PKCS#11 implementations are shared objects .so on Unix and .dll on Windows. I’m not sure if there is a version of pkcs#11 that translates between it and Microsoft Crypto API. If so, windows users should be set. On Linux, the best bet for the moment seems GPKCS11, which unfortunately hasnt been updated for a while. They provide a framework for writing pkcs#11 implementations. The example implementation wraps around OpenSSL. So far so good. I’ve been trying to build it and it coughs up compilation errors with openssl-0.9.7c. The version documented in the README is version 0.9.4, which I shall have to download and try out. I’ll report back on how it goes.
I have an old Java powered iButton lying around which should also work. They provide a PKCS#11 implementation on their site. I’m first trying to connect to it, which isnt quite as simple as it should be on Linux. I’ll report back on that as well.
Non Blocking SSL/TLS in JSSE
For most people writing a secure web application is using SSL. Now this is highly debatable and should really be questioned as SSL/TLS only provide link security and optional (generally pointless) authentication. However if we agree that link security is good, the new Non Blocking SSL support is good news. In JDK1.4 you could only apply SSL to the traditional stream based socket. However JDK1.4 also introduced a new high availability method for creating sockets using the non blocking Socket Channels. Now we can use those for SSL as well. Actually we can use them for many different kinds of situations as Sun have created a very good abstract SSLEngine, which handles the SSL protocol in a transport independent manner.
Most people will continue to use the old SSLSocket’s, however SSLEngine provides a really good interface for use in particular by server writers. You create a new SSLEngine using SSLContext and then use SSLEngine’s wrap() and unwrap() methods to encrypt and decrypt. Easy, peasy. wrap() and unwrap() both take source and destination ByteBuffer’s as arguments. These can be read or written directly using a SocketChannel or other underlying transport.
This entry was posted in the following Categories: Java