In Java, the keypair is generated as follows:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG"));
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
byte[] privateKeyBytes = pair.getPrivate().getEncoded();
byte[] publicKeyBytes = pair.getPublic().getEncoded();
The keys are then stored in files and loaded in at run time as follows:
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new
PKCS8EncodedKeySpec(privateKeyBytes));
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new
X509EncodedKeySpec(publicKeyBytes));
To sign a message, I do the following:
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(privateKey, random);
sig.update("message".getBytes("UTF-8"));
byte[] sigBytes = sig.sign();
To verify the signature, I do the following:
Signature verify = Signature.getInstance("SHA1withRSA");
verify.initVerify(publicKey);
verify.update("message".getBytes("UTF-8"));
return verify.verify(sigBytes);
I want to write a C# version of the application that can both send and
receive such signed messages. I have been seaching around and found lots of
stuff about the System.Security.Cryptography namespace, but nothing that
seems to map down to what I have in Java. Could anyone give me a few
pointers as to where to get started?
Thanks,
Phil
The PKCS #1.5 signature format generated by Java is identical to
that generated by .NET class above. For more info, see:
http://pages.istar.ca/~neutron/feature/JKeyNet
- Michel Gallant
Visual Security MVP
"Philip Ross" <psr*nospam*@*nospam*warwickcompsoc.co.uk> wrote in message
news:O8taIPW...@tk2msftngp13.phx.gbl...
I've been doing some experimentation with the .NET RSA classes. I can get
things working with pure .NET code but I can't get it to interoperate with
Java (every signature is failing verification). Could you or someone else
post some sample code?
Thanks,
Phil
The tool in JKeyNet above was designed to convert a Java 2 exported key generated by
pubkey.getEncoded(), and decode that to a Microsoft CryptoAPI PUBLICKEYBLOB
which can be easily decoded (using detailed MSDN docs for example) to get
public key modulus and exponent for .NET usage.
If you have an X509 certificate (say from Java exporting or elsewhere), then you can
look at source code in "decodecertkey", which shows how to decode any X509 cert
into key modulus and exponent, for initizing of RSAParameters and then
oRSA.ImportParameters(oRSAParameters):
http://pages.istar.ca/~neutron/feature/decodecertkey/
Next release of .NET (Whidbey ~ 2004) will have methods for this. With .NET 1.0/1.1, the
linkage between certs and CSP is rather poor so you need to manually do this (or use
some functionality in WSE ... a bit heavy if you need to deploy to clients). Doing things
manually is a good exercise in understanding some details, even if later on you
choose to use more transparent convenience methods (which in .NET are almost always
just convenience wrappers around CryptoAPI underlying implementations).
I've got things working now. Thanks for your help.
My problem was in transferring public keys (as modulus and exponent) from
Java to C#. I was exporting them using RSAPublicKey.getModulus() and
getPublicExponent() and Base 64 encoding before transferring to C#.
Unfortunately, this process caused the modulus to gain an extra 0 byte and
the exponent to lose one. I've now adapted some code from your VerifySig
program to load a PUBLICKEYBLOB file converted by your DecodeBlob utility.
Phil