我尝试验证服务器端的RSA签名,该签名是通过USB-token和.Net在客户端上签名的。
所以,我有:
公钥:
模量:
zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==指数:
AQAB
源数据:
29062015
签名base64 :
77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==
我的Java代码验证:
public static void test() {
String modB64 = "zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==";
String expB64 = "AQAB";
String phrase = "29062015";
String sign = "77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==";
PublicKey pubKey = constructPublicKey(modB64, expB64);
Log.m("ver: " + verify(pubKey, phrase.getBytes("UTF-8"), b64decode(sign)));
}
private static PublicKey constructPublicKey(String modB64, String expB64)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, UnsupportedEncodingException {
BigInteger mod = new BigInteger(b64decode(modB64));
BigInteger exp = new BigInteger(b64decode(expB64));
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(mod, exp);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
PublicKey key = keyFactory.generatePublic(keySpec);
return key;
}
private static boolean verify(
PublicKey publicKey, byte[] message, byte[] signature)
throws SignatureException, NoSuchAlgorithmException,
UnsupportedEncodingException, InvalidKeyException,
NoSuchProviderException {
Signature sign = Signature.getInstance("SHA1withRSA", "BC");
sign.initVerify(publicKey);
sign.update(message);
return sign.verify(signature);
}
private static final byte[] b64decode(String data)
throws UnsupportedEncodingException {
return Base64.getDecoder().decode(data.getBytes("UTF-8"));
}
但它总是返回假
此外,我尝试使用另一种编码(ASCII,windows-1251)与 getBytes()方法,这不解决问题。
我也尝试在没有BouncyCatle的情况下进行验证。
但是签名和密钥对必须是正确的,我猜,因为我用C#测试它并且这个工作正常:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters prsa = new RSAParameters();
prsa.Modulus = Convert.FromBase64String("zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==");
prsa.Exponent = Convert.FromBase64String("AQAB");
rsa.ImportParameters(prsa);
string data = "29062015";
string sign64 = "77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==";
byte[] dtBuffer = Encoding.Default.GetBytes(data);
byte[] sgBuffer = Convert.FromBase64String(sign64);
if (rsa.VerifyData(dtBuffer, CryptoConfig.MapNameToOID("SHA1"), sgBuffer))
result.Text += "\nRight!";
请帮帮我 Java方面有什么问题?为什么我可以通过C#验证此签名,但是不能通过Java验证?