# My opinions on Key, KeySpec, KeyFactory, KeyGenerator, et. al.

George Chung (gchung@openhorizon.com)
Mon, 9 Mar 1998 13:21:54 -0800

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: George Chung: "Fw: My opinions on Key, KeySpec, KeyFactory, KeyGenerator, et. al."
- Previous message: S Prabhakar: "Reg. Java Classes"

    From: "George Chung" <gchung@openhorizon.com>

    To: <java-security@javasoft.com>

    Subject: My opinions on Key, KeySpec, KeyFactory, KeyGenerator, et. al.

    Date: Mon, 9 Mar 1998 13:21:54 -0800

Types of java.security.Key are what are passed into the cipher/signer
implementations. In the JCE 1.2 documentation for SecretKeyFactory, it
states:

"Key factories are used to convert _keys_ (opaque cryptographic keys of type
Key) into _key specifications_ (transparent representations of the
underlying key material), and vice versa....
A provider should document the key specifications supported by its secret
key factory. For example, the SecretKeyFactory for DES keys supplied by the
Sun provider supports DESKeySpec as a transparent representation of DES
keys...
The following is an example ofhow to use a SecretKeyFactory to convert
secret key data into a SecretKey object, which can be used for a subsequent
Cipher operation:

byte[] desKeyData;
DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);"

Hypothetically, it seems like a "FOO" provider of SecretKeyFactory could
arbitrarily store each byte of the key material in a long (or a String
representation of the key in hex). If this were the case, then if a "FOO"
instance of SecretKey were passed into a "BAR" instance of a DES Cipher,
seems like the "BAR" implementation has to do a lot of work do encrypt the
buffer with "FOO" key. The BAR implementation will have to do something
like:

String format = key.getFormat()
byte encoded[] = key.getEncoded();
usableKey = convert(encoded, format); // throws EFormatNotSupported
// I have to do the above because I know neither the KeySpec nor the
Provider
...

If this _is_ the case (Ciphers from provider BAR can use Keys from provider
FOO), why not just hide the opaque Key's from the outside world? And have
Cipher.init() just take a KeySpec as a parameter? Cipher.init() could throw
a InvalidKeySpecification exception. In general, I'm not seeing much value
in the Key interface methods now that JDK 1.2 and the JCE provide a KeySpec
class heirarchy.

If this is _not_ the intention (Ciphers from provider BAR can only use Keys
from provider BAR), then it seems that instances of KeyGenerator and
KeyFactory should be returned by new factory methods off of Cipher (or
Signature). Otherwise, someone could wreak havoc by installing a
java.security.provider implementation at position 1 and only providing a DES
KeyGenerator implementation. This suggestion would _better_ the chances of
preventing an error, but certainly not eliminating it.

Perhaps one way to completely eliminate the possibility of error is to
completely eliminate the Key interface (as it currently exists) and to have
Cipher simply deal with KeySpec's. For example:

void Cipher.init(int mode, KeySpec keyspec);
KeySpec Cipher.generateKey();

There is no need for a KeyFactory...those details are hidden inside the
Cipher implementation. There's no need for KeyGenerator either. Cipher
becomes the factory class for new KeySpec's that can be used with all
providers of Cipher (which are of the same algorithm).

Note, we can accomplish the same thing with minimal disruption by making
KeySpec extend Key. That way the above would change to:

void Cipher.init(int mode, Key key);
Key Cipher.generateKey();

But I think we can still get rid of KeyFactory and KeyGenerator.

Just my 2 cents.

Regards,
George Chung
Open Horizon, Inc.

- Next message: George Chung: "Fw: My opinions on Key, KeySpec, KeyFactory, KeyGenerator, et. al."
- Previous message: S Prabhakar: "Reg. Java Classes"