Search code examples
androidbase64digital-signaturedsa

Android: DSA signatures - sign and verify


I am having problems verifying a signature which I've just created. After signing I first convert the signature to text using Base64 and as a test I wanted to verify that I can decode the Base64 and verify the signature. This fails. Here is some code without the error handling.

I have my keypair:

DSAPrivateKey privateKey = (DSAPrivateKey) keyPair.getPrivate();
DSAPublicKey publicKey = (DSAPublicKey) keyPair.getPublic();

Now I sign some text and print to log output - it seems fine:

String text = "test";
Signature signer = null;
signer = Signature.getInstance(privateKey.getAlgorithm());
SignedObject signedObject = null;
signedObject = new SignedObject(text, privateKey, signer);
String print_signature = Base64.encodeToString(signedObject.getSignature(), Base64.DEFAULT);
System.out.println("Base64 Signature: " + print_signature);

Now I verify the signature using the SignedObject object created above and not the Base64. This is successful:

Signature verifier = null;
verifier = Signature.getInstance(publicKey.getAlgorithm());
boolean b = signedObject.verify(publicKey, verifier));

For my app I will only have the public certificate of the signer and the Base64 encoded string so I must verify the signature using these parameters only and can therefore AFAIK not use a SignedObject object. I used the Signature object:

Signature verifier1 = null;
verifier1 = Signature.getInstance(publicKey.getAlgorithm());
verifier1.initVerify(publicKey);
verifier1.update(text.getBytes()); // sorry I forgot this in original posting
byte[] sig1 = Base64.decode(print_signature, Base64.DEFAULT);
b = verifier1.verify(sig1));

This verification always fails (b = false).


Solution

  • Why are you using the SignedObject in the first place? What does it buy you? As for the verify failure, make sure that you get the same bytes after transmission/receiving. Are you sending/receiving in the same encoding? Is someone modifying the string?