Here is the setup:
I create public/private key pair with .NET, I want to sign a string. I take a random string, get a byte[] from it, sign it, and take the signature in the java app. I want to verify it in java ( (!)I'm talking about Android's java).
The process to take the public key to Java environment: When I create the public key, I take the byte arrays for the public key (P, Q, G, Y) and create PublicKey in Java with those values. P, Q, G, Y in .NET are byte[], I convert them to sbyte[] and use these sbyte[] in Java, creating big integers:
byte[] byteP = new byte[] { -34, ...... -117 };
...
BigInteger p = new BigInteger(1,byteP);
...
new DSAPublicKeySpec(y, p, q, g);
To test the process, I take the signature byte[] from C#, convert it to sbyte[] and then use it in Java.
The problem is, I cannot verify the signature string later. I got
java.security.SignatureException: signature bytes have invalid encoding
Any ideas appreciated! (Like, a better, entirely different way to do the whole thing ;) )
A DSA signature is actually two numbers and there is no real standard for how to format this as a bytearray.
Java chooses to encode it as the DER-encoding of an ASN.1-sequence containing two ASN.1-integers.
.NET chooses to prepend zeroes to the two numbers so they are exactly 20 bytes long and concatenate them.
To convert from .NET to Java format do something like this (untested, but should be mostly correct):
}
Not sure if I am throwing you off on a goose chase here, but (Sun's!) BigInteger uses the 1 you pass in the constructor as the signum of the number - so it could have an impact on the resulting signature calculation ... I've had issues with this in the past using RSA ...