用Java实现SHA1withRSA

时间:2019-04-11 19:39:22

标签: java c++ encryption cryptography rsa

我正在尝试将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作为签名。 gsgs_sig已知,分别为96和256个字节。

测试值:

serverKey: ace0460bffc230aff46bfec3bfbf863da191c6cc336c93a14fb3b01612acac6af180e7f614d9429dbe2e346643e362d2327a1a0d923baedd1402b18155056104d52c96a44c1ecc024ad4b20c001f17edc22fc43521c8f0cbaed2add72b0f9db3c5321a2afe59f35a0dac68f1fa621efb2c8d0cb7392d9247e3d7351a6dbd24c2ae255b88ffab73298a0bcccd0c58673189e8bd3480784a5fc96b899d956bfc86d74f33a6781796c9c32d0d32a5abcd0527e2f710a39613c42f99c027bfed049c3c275804b6b219f9c12f02e94863eca1b642a09d4825f8b39dd0e86af9484da1c2ba863042ea9db3086c190e48b39d66eb0006a25aeea11b13873cd719e655bd
gs: 4f2d7c6e76ccb6400ae1ff560d55a8084d98563ae03ac109d899fde735f6490935383cd1a97aa1fbff12e646f837194e9c6e57e1c5f956fcfde446a387c6be9a35c3225475f86df5a2c9b94626a2f90da3673af9861e33e8851a9a0ae20b9809
gs_signature: 35d1e685382f6d75bc5991f8ca1d252d70851c7bf66aa332bc6fc37bdb95da40c77c3cb452e6a70feda2bd6f63036d4b7a6d3f205789cf23a5777bcbd917a803ec2f3fb47fb6bdb911dd7d40dbe8425ad0d1905f1edb1bbc037ef4e259fa9c5dacdf9d58db8a18baf593d4e1c8055f51acffdaeeb10b4cee79f8b2421cfc28bdc9513859f76b101c965427334927207b575b9c29c581dfcc6fa4f135a1b04cfda4363e589f0510407faec4041b142b0ebbb9acd26dc2ed54fb28c38f560e05f8048c08c3574a4865f903192636987021eb72598ee822544026756ca294a150eb6642e65a860bac31fbba5ca0d800d030a52b515a7b8768def7de8e9f5dccdebe
gs_hash: 41aed19785bc5f4ffaa7eb30a29b1a39d52a225a

1 个答案:

答案 0 :(得分:1)

有两件事是错误的:

  1. 在使用"SHA1withRSA"时,您不需要对自己进行哈希处理(签名将为您进行哈希处理,只需将数据提供给它即可)
  2. 如果添加"/PSS",则说明您使用的是与PKCS#1 v1.5不同的方案。

BigInteger(byte[])如果与模数一起使用,将创建一个负值。您需要使用BigInteger(1, byte[])使其为正值。但是,作为JCE的Bouncy都应在负指数上抛出异常,因此无论如何我都看不到如何使代码运行。