I've been working with a group to implement a JCE/JCA service provider for
a hardware crypto product, the Eracom CSA 7000. The hardware allows
for in place generation and encryption of session keys, as in generate the
session key on the board, download (if necessary) the appropriate public
key, encrypt the session key using the public key on the board, and then
return the encrypted encoding of the key to the world outside the board. Any
encryption using the session key also takes place on the hardware. In general
a key object for the Eracom provider is just a reference to a key table
on the hardware, the actual key material lives on the hardware, hidden from
view.
Being able to lock down a session key so that it nevers leaves the hardware is
regarded as a good thing (it sits well in a universe of total paranoia!), however
there is no support for this feature in the JCA/JCE at the moment. After some
wrestling I have got, what I believe to be, a solution, basically I've provided a
class in the eracom package which defines a WrappingKeyStore
which is, essentially, a key store with two extra methods, and a SPI class,
WrappingKeyStoreSpi, which is an extension of KeyStoreSpi. This allows
me to use the same provider class for KeyStore and WrappingKeyStore, anyway
the SPI class is attached below, any comments on this would be most welcome,
(I've run it past a few people, but...) and, yep, you could regard this as a request
for enhancement! I realise, for full effect, key wrapping requires special purpose
hardware, but I believe it would be good to be able to program in such a fashion
that the benefit of the hardware would be realised whenever it was available.
Thanks,
David.
PS. an example of use:
WrappingKeyStore wrapKeyStore;
wrapKeyStore = WrappingKeyStore.getInstance(type, provider);
...
//
// wrap a key.
//
byte[] enc;
RSAPublicKey wrapKey;
Key key;
String alg;
...
alg = key.getAlgorithm();
enc = wrapKeyStore.wrapKey(wrapKey, "RSA/ECB/PKCS1Padding", key);
...
//
// unwrap a key.
//
Key newKey;
newKey = wrapKeyStore.unwrapKey(
wrapKey, "RSA/ECB/PKCS1Padding", enc, alg);
----------------------------------------------------------
package au.com.eracom.crypto;
import java.security.*;
import javax.crypto.*;
/**
* An extension to KeyStoreSpi to define a key wrapper. This SPI can be
* be implemented by hardware key stores which have the ability
* to encrypt/decrypt a key in place without exposing it outside the hardware.
*/
public abstract class WrappingKeyStoreSpi extends KeyStoreSpi
{
/**
* Wrap a key.
*
* @param wrapKey the key to be used to do the wrapping.
* @param transformation the transformation to be used.
* @param key the key to be wrapped.
* @exception GeneralSecurityException if the cipher couldn't be set up,
* padding, or modes, were unavailable, or the wrapKey is invalid.
* @return an encrypted encoding of the key.
*/
public abstract byte[] engineWrapKey(
Key wrapKey, String transformation, Key key)
throws GeneralSecurityException;
/**
* Unwrap a previously wrapped key.
*
* @param unwrapKey the key to use for the unwrapping.
* @param transformation the transformation to be used.
* @param wrappedKey the key to be unwrapped.
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
* @exception GeneralSecurityException if the cipher couldn't be set up,
* padding, or modes, were unavailable, or the unwrapKey is
* invalid.
* @return a reference to the key constructed from the decrypted
* encoding in wrappedKey.
*/
public abstract Key engineUnwrapKey(
Key unwrapKey, String transformation,
byte[] wrappedKey, String wrappedKeyAlgorithm)
throws GeneralSecurityException;
}