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


#1

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@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#2

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@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

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


#3

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@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

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

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


#4

Hello Werner,

Your response solves the problem and explains everything in detail which, in
my opinion, is important, thank you :slight_smile:

kind regards,
George.

···

On Sat, Jul 11, 2009 at 10:35 AM, Werner Dittmann < Werner.Dittmann@t-online.de> wrote:

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@sip-communicator.dev.java.net
>> For additional commands, e-mail: dev-help@sip-communicator.dev.java.net
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
> For additional commands, e-mail: dev-help@sip-communicator.dev.java.net
>
>

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