DSA and ECDSA signature format is incompatible with XMLDSig
Sean Mullan
sean.mullan at oracle.com
Mon Jul 19 19:36:10 UTC 2010
Hi Maarten,
Thanks for the comments, a few replies below -
Maarten Bodewes wrote:
>
>
> On Thu, Jul 15, 2010 at 6:57 PM, Sean Mullan <sean.mullan at oracle.com
> <mailto:sean.mullan at oracle.com>> wrote:
>
> I would like to try to fix a long-standing XMLDSig issue with the
> current DSA and ECDSA signature bytes format.
>
> The format of the Signature bytes for these algorithms is an ASN.1
> encoded sequence of the integers r and s:
>
> SEQUENCE ::= { r INTEGER, s INTEGER }
>
> Unfortunately, this is not compatible with XMLDSig (and other
> signature formats like .NET), which doesn't ASN.1 encode them and
> simply base64 encodes the raw bytes of r and s concatenated (the
> IEEE P1363 format).
>
>
> There are more standards that use the P1363 format. Personally I'm
> involved with the EAC specification for ePassports & Java. You'll find
> this kind of signature if you look at the EAC certificates for the
> inspection systems (and their CA's).
>
>
>
> So, our XMLDSig implementation always has to strip off, or decode
> the ASN.1 stuff after calling Signature.sign() when generating
> signatures, and ASN.1 encode the signature bytes before calling
> Signature.verify() when verifying signatures. I could live with this
> until now because it was limited to DSA which wasn't in wide use.
> But now the same problem comes up with ECDSA.
>
>
> That is a very well known situation for me :). I don't directly remember
> though if I had to do normalization on the integers as well (stripping
> of 00h bytes at the front or adding 00h bytes to get to the correct
> bit-size of the signature elements), or if s & r were encoded as ASN.1
> octet strings.
Yes, your memory is correct.
> I would really like to clean this up. There seems to be a couple of
> ways we could fix this:
>
> 1. Add new standard signature format strings that identify the
> format: ex:
>
> SHA1withDSAandP1363
> SHA1withECDSAandP1363
> SHA256withECDSAandP1363
> SHA384withECDSAandP1363
> SHA512withECDSAandP1363
>
> I like this the best, but one issue with this is that the "and"
> extended format is reserved for MGF functions, ex: MD5withRSAandMGF1
> and this is not a mask generation function. My suggestion is that we
> use a keyword (ex: Format) that clearly distinguishes it from an MGF:
>
> <digest>with<encryption>and<format>Format
>
> ex:
>
> SHA256withECDSAandP1363Format
>
>
> I second this solution, since they would also be usable by other
> applications. I've got a serious problem with the solution though:
> hardware providers may not support it. And if HW providers do not
> support it then you need to work around it. Fortunately, if I'm not
> mistaken, you can work around this by creating a very simple provider
> that performs the wrapping/unwrapping of the signature (as you don't
> need to sign).
Yes, but I believe this is no different than what is done today. The
Java provider does the DER encoding/decoding and the underlying hardware
impl does the verification/signing.
> Of course, by now the string build-up of the signature format is getting
> really complicated (you could say it is starting to imitate life). In
> the end it might be a good idea to replace it by something that can be
> selected/verified at compile time (e.g. a list of signature parameters).
> Currently it might be a good idea to create a constant somewhere for
> these kind of strings.
Yes, point taken. In practice though this should not be too much of an
issue. We'll document the new algorithms in the standard algorithms
document [1] so developers can cut-paste them into their code.
> 3. Add a higher level DSA/ECDSA Signer API that returns the r and s
> as BigIntegers and leaves the encoding of those bytes to the
> application.
>
> This is a very clean solution, but is more of a significant API
> change as it would be introducing a new higher level API for
> generating/validating signatures.
>
>
> Would that not be a *lower* level API, since it does not do the
> encoding?
Yes, if you look at it that way. Actually, probably another solution
would be to enhance the Signature API to support algorithm-specific
signature objects (instead of bytes), but I would be very hesitant to do
that just to support this option.
> Of course, in the end we might want to replace the current JCA with one
> that uses the factory principle and immutable Signer and Verifier
> classes, but that is an entirely different discussion :)
>
>
>
> 4. Do nothing
>
> Live with it :(
>
>
> Nah, if you want to go for 1), then go for it. No current code would
> break, it's a standardized algorithm you are implementing and other
> people like me are using it.
Thanks.
--Sean
[1]
http://download-llnw.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes/guides/security/StandardNames.html
More information about the security-dev
mailing list