Date: Tue, 11 May 1999 09:45:38 +1000
From: Bernard Leach <leachbj@aba.net.au>
To: java-security@java.sun.com
Subject: Re: Anyone else trying to write code to work with a provider other than
DavidTaylor wrote:
>
> 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?
Good question! Public key's only it would seem, and
PKCS8EncodedKeySpec's are
used for the 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.
Its all out there, just hard to find... Perhaps Sun is being (overly?)
cautious of the "lending technical assistance" side of their crypto
regulations?
> 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.
At least the source code for that is available now, which makes things
a little easier.
> 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:
>
> [...]
Thats not real fun. Get on their case :)
> 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...
That is a definite mis-feature. The ECB,CBC,OFB modes are all
well-known
standards!
> 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.
That is not too unreasonable. Applications should only pass either
KeySpec
classes or that provider's keys to a provider class. The various
factory
classes are used to convert between the provider key and the
provider-independent
keyspec.
> 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).
Agreed. The IV question is basically answered by the doFinal
documentation
(it says that after a doFinal the cipher is set to the state it was
after the
last call to init).
> 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.
Strange, I would have thought that if you were to implement a KeyFactory
you would first do the import function (generateSecret) and then the
export function (translateKey). I mean you want people to be able to
generate keys for _your_ provider!
> 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.
I think its good practice to allow for SecretKeySpecs wherever
possible. They
are great for testing. When I first saw the SecretKeySpec class though
I
didn't realise it was a Key instance so I made our KeyFactories convert
them
into keys (which isn't so bad), but its much easier to just allow them
in the
Cipher's init() method!
> 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.
The "How-to" document could also be a little more pro-active here
suggesting
that if you implement a cipher what the minimum functionality should be.
> 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.
>
> [...]
>
> 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?
You are using CBC mode so avoid codebook attacks. Unfortunately in your
case the JCE API is working against you, because to it your protocol
looks
like a number of dis-joint messages, and because of that you have to do
the inter-message chaining.
> 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 specification in my mind is fairly clear, as far as a Cipher goes
you can
supply data to it and once you call doFinal you will have all the result
data, but until then nothing is guaranteed...
> 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.
Yours is the second message I've seen where people have had real
problems
in writing cross-provider code. The problems seem to stem from;
1. No enough standardarisation for algorithm names. E.g. is the "RSA"
Cipher
an implementation of RSA PKCS#1 or RSA as in X.509? What is the
standard
name for a DES based Mac algorithm?
2. No "minimal functionality" required for cross-provider
compatibility. E.g. if
a provider includes a Cipher what functionality should it minimally
support
to be compatible with other providers.
3. Non-conformance with JCE specification, due to bugs or otherwise.
One thing I think that would really improve things is a publication of
the Java compatibility kit for the JCE. At one stage I thought we might
see this after Java2 was released but my optimism has diminished
somewhat.
An expanded "How-to" document with guide-lines on what parts of the
API are important for cross-compatibility would be most helpful too.
bernard.