Date: Mon, 10 May 1999 11:37:50 +1000
From: DavidTaylor <DavidTaylor@forge.com.au>
To: java-security@java.sun.com
Subject: Anyone else trying to write code to work with a provider other than
Firstly, thanks for the clarification on doFinal and CBC mode.
Some more comments on trying to work with different JCEs and providers:
I have written a provider and I've tested those from IAIK, DSTC and ABA. And
they're all different :( Makes it impossible to write provider independent code!
The frustrations I've had with RSA in different providers:
What exactly goes into an X509EncodedKeySpec? Can it be used for both public and
private keys? RSAPrivateKeySpec and RSAPrivateCrtKeySpec are both obvious enough
but some providers never bother to check if the Crt interface has been passed in
and always just return an RSAPrivateKey. How about PKCS8EncodedKeySpecs? The key
spec type and the exact ASN.1 encoded data (or whatever else) acceptable to it
should be written in stone. Public keys too. I had to figure out what the Sun
CertificateFactory was passing into my key factory when a certificate was being
parsed - that info should have been in either the Certificate or RSAKeyFactory
documentation.
I've had to modify other people's providers to get a common code base. The one's
I can't modify I just can't use. That's obviously not what you want for the JCE!
Some examples:
* ABA RSAKeyFactory private key options
* -------------------------------------
* AsciiEncodedKeySpec (their own spec): either an RSAPrivateKey or
RSAPrivateCrtKey depending on how much info in the spec
* PKCS8EncodedKeySpec: RSAPrivateCrtKey
* RSAPrivateCrtSpec: RSAPrivateCrtKey
* RSAPrivateKeySpec: RSAPrivateKey
*
* DSTC RSAKeyFactory private key options
* --------------------------------------
* RSAPrivateCrtSpec: RSAPrivateKey (they don't check for this so it's caught
as an RSAPrivateKeySpec)
* RSAPrivateKeySpec: RSAPrivateKey
* PKCS8EncodedKeySpec: RSAPrivateCrtKey
* X509EncodedKeySpec: RSAPrivateCrtKey
*
* FORGE RSAKeyFactory private key options
* ---------------------------------------
* RSAPrivateCrtSpec: RSAPrivateCrtKey
* RSAPrivateKeySpec: RSAPrivateKey
* EncodedKeySpec: RSAPrivateCrtKey
Onto the RSA cipher itself:
One provider wanted "RSA/ECB/NoPadding" and another wanted "RSA/1/NoPadding" or
"RSA/2/NoPadding" and used the 1 or 2 to set some internal state...
Other providers have choked when you passed them a key from another key factory -
they'd only use their own key implementations! Related to this is the provider
that requires RSAPrivateCrtKeys and won't work with RSAPrivateKeys.
CBC/IV clarification:
Clarifying the IV lifecycle and whether the input and output buffers can be the
same in an update/doFinal call in the specification seems necessary (not just a
FAQ somewhere).
Secret key creation and cipher use:
Provider secret key factories have different requirements. Some don't have
algorithm specific secret key factories meaning you use SecretKeySpecs to pass in
raw keys. If they do have algorithm specific factories some of them require you
use the generateSecret method and some of them require the translateKey method to
be used.
Should all "bulk" ciphers be forced to accept SecretKeySpec as their keys during
the init call? If I can't get a secret key factory I have no choice.
So I've seen: some providers don't give secret key factories so you give the
cipher a SecretKeySpec, but some providers won't accept that and require you to
use a secret key factory - although these ones want you to call different methods
with the secret key spec.
To be fair, some of this seems to have been caused by implementation being done
against outdated versions of the spec. But most of it is because the
specification isn't laying the law clearly enough.
Another point of contention here is update/doFinal themselves. Sorry if you know
this but I'll give a simple overview of the SSL protocol, after the key exchange
has been completed:
The block ciphers have been initialised in CBC mode with a secret key and IV
agreed up during the key exchange. There is one cipher for reading and one for
writing.
A typical encrypted FTP session from the point of view of the client might go:
A: -> USER username (sent using send cipher - write cipher IV is updated)
(waits for response)
A: <- PASSWORD required (read using read cipher - read cipher IV is updated)
(waits for response)
A: -> PASS password (sent using send cipher - write cipher IV is updated)
A <- user logged in, waiting for command (read using read cipher - read cipher IV
is updated)
So, there are pauses in the conversation both ways. The cipher cannot be
reinitialised at any point as CBC mode is being used and the IV will be reset.
All data is sent and received in mulitples of the block size - this is required
by SSL.
I am being told to use doFinal between messages to ensure things work correctly.
Clearly that is not an option unless I keep track of the IV each step of the way
so I can initialise the cipher with it between messages. If I'm going to do that,
why would I bother using CBC mode? Should the above be possible without
initialising the cipher betwee messages?
This was brought up becuase I've been told some providers that sit on top of
hardware will cause me grief by buffering data or whatever. This is another area
that could use some clarification or example in the specification.
The current game plan seems to be for everyone to write their own provider and
use that. I'm trying to write software that uses a JCE and whatever providers the
user wants and I'm having a hard time of it.
I've spent a lot of time reworking our software to use the JCE and providers and
sold management on the benefits of not writing our own and now have some egg on
my face.
I like the idea of the JCE and providers, and I'm very impressed that people like
ABA and DSTC have put their code out as they have (as have FORGE). Sadly, we had
to do too much interpretation of the spec ourselves and have all done it
differently. I'm just pointing out the interoperability problems I've had so you
can make that spec more clear!
--Regards, David Taylor
======================================================================= David Taylor e-mail DavidTaylor@forge.com.au Software Engineer Forge Research Pty Ltd Phone +61 2 9209 4175 PO Box 598, Alexandria Fax +61 2 9209 4172 NSW 1435, Australia Web http://www.forge.com.au =======================================================================