Reputation: 183
I'm working on implementing Bing Cashback. In order to verify an incoming request from Bing as valid they provide a signature. The signature is a 160-bit SHA-1 hash of the url encrypted using RSA.
Microsoft provides the RSA "public key", modulus and exponent, with which I'm supposed to decrypt the hash.
Is there a way to create the Java key objects needed to decrypt the hash as Microsoft says?
Everything I can find creates RSA key pairs automatically since that's how RSA is supposed to work. I'd really like to use the Java objects if at all possible since that's obviously more reliable than a hand coded solution.
The example code they've provided is in .NET and uses a .NET library function to verify the hash. Specifically RSACryptoServiceProvider.VerifyHash()
Upvotes: 18
Views: 20727
Reputation: 269697
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(spec);
Signature verifier = Signature.getInstance("SHA1withRSA");
verifier.initVerify(pub);
verifier.update(url.getBytes("UTF-8")); // Or whatever interface specifies.
boolean okay = verifier.verify(signature);
Upvotes: 38
Reputation: 61378
Use java.security.spec.RSAPublicKeySpec. It can construct a key from exponent and modulus. Then use java.security.KeyFactory.generatePublic() with key spec as a parameter.
Upvotes: 3
Reputation: 11733
Something like this should do the trick:
private PublicKey convertPublicKey(String publicKey) throws Exception{
PublicKey pub = null;
byte[] pubKey = Hex.decodeHex(publicKey.toCharArray());
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
pub = (RSAPublicKey) keyFactory.generatePublic(pubSpec);
return pub;
}
This assumes the Public key is given as a hex string, and you'll need the Apache Commons Codec library
If you have the key in a different format, try the KeyFactory for more information.
Upvotes: 1