[sip-comm-dev] DSA Signature sign/verify using BC/Standard JCE

Werner Dittmann Werner.Dittmann at t-online.de
Sat Jul 11 10:35:37 CEST 2009


George,

IMHO the following code snippets explain why this goes wrong:

    private static byte[] signWithStandardJCE(byte[] b, PrivateKey privatekey)
            throws NoSuchAlgorithmException, InvalidKeyException,
            SignatureException {

        Signature signer = Signature.getInstance(privatekey.getAlgorithm());
        signer.initSign(privatekey);
        signer.update(b);
        return signer.sign();
    }

This code takes the data (byte[] b) and calls signer.update(b). This in turn
is just another way of calling "digest.update(b)". Because you did not specify
any particular digest when creating the Signer this is the SHA1 digest. When
calling signer.sign() the Signer calls digest.doFinal() to get the digest
of "b" and then signs it. Thus it signs the SHA1 hash of b.

Now the BC code:

    private static BigInteger[] signWithBC(byte[] b, PrivateKey privatekey)
            throws NoSuchAlgorithmException, InvalidKeyException,
            SignatureException {

        if (!(privatekey instanceof DSAPrivateKey))
            throw new IllegalArgumentException();

        DSAParams dsaParams = ((DSAPrivateKey) privatekey).getParams();
        DSAParameters bcDSAParams = new DSAParameters(dsaParams.getP(),
                dsaParams.getQ(), dsaParams.getG());

        DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privatekey;
        DSAPrivateKeyParameters dsaPrivParms = new DSAPrivateKeyParameters(
                dsaPrivateKey.getX(), bcDSAParams);

        DSASigner dsaSigner = new DSASigner();
        dsaSigner.init(true, dsaPrivParms);

        return dsaSigner.generateSignature(b);
    }

This code sets up alle necessary parameters first, then creates and initializes
the DSASigner. Then you directly call "generateSignature(b)" - BC lightweigth
now signs b directly, not the hash of b. Thus you need to hash b first using
the same hash as above (SHA1) and then call generateSignature(hashedB):

      Digest digest = new SHA1Digest();
      digest.reset();
      digest.update(b, 0, b.length);
      byte[]  hashB = new byte[digest.getDigestSize()];
      digest.doFinal(hashB, 0);
      BigInteger[] sig = signer.generateSignature(hashB);

Of course the same holds true for signature verification: first hash, then verify.


Regards,
Werner




Werner Dittmann schrieb:
> George,
> 
> are these test part of your OTR4J library available at google code?
> 
> Regards,
> Werner
> 
> 
> Geekius Caesar schrieb:
>> Hi all,
>>
>> If there's anyone crypto-savvy around here, I'd really appreciate it
>> if he could have a look at this test cases http://pastebin.ca/1490739
>> and tell me why 2 of them fail.
>>
>> Thanks in advance.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe at sip-communicator.dev.java.net
>> For additional commands, e-mail: dev-help at sip-communicator.dev.java.net
>>
>>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe at sip-communicator.dev.java.net
> For additional commands, e-mail: dev-help at sip-communicator.dev.java.net
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe at sip-communicator.dev.java.net
For additional commands, e-mail: dev-help at sip-communicator.dev.java.net





More information about the dev mailing list