我正在尝试将C ++程序移植到Java,但没有太多运气。使用的算法是RSASSA-PKCS1-v1_5
。
我知道Java在加密方面的表现与许多其他语言不同。
这已知有效:
bssl::UniquePtr<RSA> rsa(RSA_new());
rsa->n = BN_bin2bn(server_key, sizeof(server_key), nullptr);
rsa->e = BN_new();
BN_set_word(rsa->e, 65537);
std::uint8_t gs_hash[20];
SHA1(gs.data(), gs.size(), gs_hash);
if (1 != RSA_verify(NID_sha1, gs_hash, sizeof(gs_hash), gs_sig.data(), gs_sig.size(), rsa.get())) {
// failed
}
我目前的实施:
Security.addProvider(new BouncyCastleProvider());
byte[] serverKey = new byte[] {...};
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(new RSAPublicKeySpec(new BigInteger(serverKey), BigInteger.valueOf(65537)));
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] gs_hash = digest.digest(gs);
Signature sig = Signature.getInstance("SHA1withRSA/PSS", "BC");
sig.initVerify(publicKey);
sig.update(gs_hash);
if (sig.verify(gs_sig)) System.out.println("ALL GOOD");
else System.out.println("FAIL");
我也尝试过使用SHA1withRSA
进行签名。 gs
和gs_sig
是已知的,分别为96和256字节长。
测试值:
serverKey: ace0460bffc230aff46bfec3bfbf863da191c6cc336c93a14fb3b01612acac6af180e7f614d9429dbe2e346643e362d2327a1a0d923baedd1402b18155056104d52c96a44c1ecc024ad4b20c001f17edc22fc43521c8f0cbaed2add72b0f9db3c5321a2afe59f35a0dac68f1fa621efb2c8d0cb7392d9247e3d7351a6dbd24c2ae255b88ffab73298a0bcccd0c58673189e8bd3480784a5fc96b899d956bfc86d74f33a6781796c9c32d0d32a5abcd0527e2f710a39613c42f99c027bfed049c3c275804b6b219f9c12f02e94863eca1b642a09d4825f8b39dd0e86af9484da1c2ba863042ea9db3086c190e48b39d66eb0006a25aeea11b13873cd719e655bd
gs: 4f2d7c6e76ccb6400ae1ff560d55a8084d98563ae03ac109d899fde735f6490935383cd1a97aa1fbff12e646f837194e9c6e57e1c5f956fcfde446a387c6be9a35c3225475f86df5a2c9b94626a2f90da3673af9861e33e8851a9a0ae20b9809
gs_signature: 35d1e685382f6d75bc5991f8ca1d252d70851c7bf66aa332bc6fc37bdb95da40c77c3cb452e6a70feda2bd6f63036d4b7a6d3f205789cf23a5777bcbd917a803ec2f3fb47fb6bdb911dd7d40dbe8425ad0d1905f1edb1bbc037ef4e259fa9c5dacdf9d58db8a18baf593d4e1c8055f51acffdaeeb10b4cee79f8b2421cfc28bdc9513859f76b101c965427334927207b575b9c29c581dfcc6fa4f135a1b04cfda4363e589f0510407faec4041b142b0ebbb9acd26dc2ed54fb28c38f560e05f8048c08c3574a4865f903192636987021eb72598ee822544026756ca294a150eb6642e65a860bac31fbba5ca0d800d030a52b515a7b8768def7de8e9f5dccdebe
gs_hash: 41aed19785bc5f4ffaa7eb30a29b1a39d52a225a
有两件事是错的:
"SHA1withRSA"
时你不需要自己哈希(签名会为你做散列,只需要输入数据)和"/PSS"
,那么你使用的是与PKCS#1 v1.5不同的方案。如果与模数一起使用,BigInteger(byte[])
将创建负值。您需要使用BigInteger(1, byte[])
使其成为正值。但是,作为JCE的Bouncy都应该对负指数抛出异常,所以我不知道你是如何让你的代码运行的。