为什么尽管使用了相同的参数,为什么签名验证不起作用?
我很难进行此简单测试以验证签名工作。我有来自同一密钥店的公共和私钥,我执行了签名和验证的确切步骤,但是验证始终是错误的。
我应该怀疑一些编码问题吗?
@Test
public void authShouldBeOk() throws Exception {
//
String initialMessage = pCrypto.getKey();
Signature sign = Signature.getInstance("SHA256withRSA");
String paramPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArWTAz/TDWyrbXGKva+8ankn/USEmUSj1UM3JQkYnX1ilWxd0kCb+PodWcrp/l4rbBef5xyFIIEZmkWNFuIUVKUvPX35Fg4DVvhbZekMRIjh4lRBi3wyXV41OqTNr35eYBiFbHYJwLeUn5eeQqB0h4S7NmPCV1t6Ih5TWOO8vLJLC0wEwEzapopXkISj9FNXHwQHHzQGvSnqxQhWBLYwFJ9ECGNDXzlALHzshM1EGthKe5zddQoRm63bxGuBsxa75qJdmOcL/xLMnad3/FPntNcC573VM83aI0xh2lzQqhG4ZzjNvVUH+NiYwDmZgE9DVk9vP3XwR/1anBz11vTwksQIDAQAB";
Cipher cipher = Cipher.getInstance("RSA");
byte[] privBytes = pCrypto.getPriv().getEncoded();
cipher.init(Cipher.ENCRYPT_MODE, pCrypto.getPriv());
byte[] encrypted = cipher.doFinal(initialMessage.getBytes());
String encryptedMessage = Base64.getEncoder().encodeToString(encrypted);
sign.initSign(pCrypto.getPriv());
sign.update(encrypted);
byte[] signatureBytes = sign.sign();
String signatureMessage = Base64.getEncoder().encodeToString(signatureBytes);
PublicKey certP = pCrypto.getPublic();
sign.initVerify(certP);
sign.update(signatureBytes);
boolean b = sign.verify(signatureBytes);
// should be true
assert(b)
// when
authController.getAuth(encryptedMessage, signatureMessage, paramPublicKey);
}
I have trouble making this simple test for verifying a signature work. I have the Public and Private Key from the same Keystore, I do the exact steps for signing and verifying, but yet the verifying is always false.
Should I suspect some encoding problem?
@Test
public void authShouldBeOk() throws Exception {
//
String initialMessage = pCrypto.getKey();
Signature sign = Signature.getInstance("SHA256withRSA");
String paramPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArWTAz/TDWyrbXGKva+8ankn/USEmUSj1UM3JQkYnX1ilWxd0kCb+PodWcrp/l4rbBef5xyFIIEZmkWNFuIUVKUvPX35Fg4DVvhbZekMRIjh4lRBi3wyXV41OqTNr35eYBiFbHYJwLeUn5eeQqB0h4S7NmPCV1t6Ih5TWOO8vLJLC0wEwEzapopXkISj9FNXHwQHHzQGvSnqxQhWBLYwFJ9ECGNDXzlALHzshM1EGthKe5zddQoRm63bxGuBsxa75qJdmOcL/xLMnad3/FPntNcC573VM83aI0xh2lzQqhG4ZzjNvVUH+NiYwDmZgE9DVk9vP3XwR/1anBz11vTwksQIDAQAB";
Cipher cipher = Cipher.getInstance("RSA");
byte[] privBytes = pCrypto.getPriv().getEncoded();
cipher.init(Cipher.ENCRYPT_MODE, pCrypto.getPriv());
byte[] encrypted = cipher.doFinal(initialMessage.getBytes());
String encryptedMessage = Base64.getEncoder().encodeToString(encrypted);
sign.initSign(pCrypto.getPriv());
sign.update(encrypted);
byte[] signatureBytes = sign.sign();
String signatureMessage = Base64.getEncoder().encodeToString(signatureBytes);
PublicKey certP = pCrypto.getPublic();
sign.initVerify(certP);
sign.update(signatureBytes);
boolean b = sign.verify(signatureBytes);
// should be true
assert(b)
// when
authController.getAuth(encryptedMessage, signatureMessage, paramPublicKey);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,在签名和验证时,您不会执行相同的步骤:使用
sign.update(加密)>
加密
的内容已签名。因此,当验证时,必须使用sign.update(加密)
,而是应用sign.update(signaturebytes)
。如果解决此问题,则验证成功。除此之外,尚不清楚为什么您使用私钥来加密消息。使用公钥执行加密。 Java从技术上讲,Java允许使用私钥进行加密,但这实际上是用于低级签名,而不是保密性的加密(这也毫无意义,因为任何人都可以解密公共密钥)。
请注意,在实例化
cipher
对象时,应指定填充物,例如rsa/ecb/pkcs1padding
,否则使用依赖于提供商的默认值。此外,编码/解码应指定所使用的字符集,例如
initialMessage.getBytes(standardCharsets.utf_8)
,否则应用了平台依赖默认值。都可以导致加密和解密性不足。 。
No, you don't perform the same steps when signing and verifying: When signing with
sign.update(encrypted)
the content ofencrypted
is signed. Therefore, when verifying,sign.update(encrypted)
has to be used, but insteadsign.update(signatureBytes)
is applied, which is why verification fails. If you fix this, verification is successful.Apart from that, it is unclear why you are using the private key to encrypt the message. Encryptions are performed with the public key. Java technically allows encryption with the private key, but this is actually for low level signing, not encryption for confidentiality (which would also be pointless, since anyone could decrypt with the public key).
Note that the padding should be specified when instantiating the
Cipher
object, e.g.RSA/ECB/PKCS1PADDING
, otherwise provider dependent default values are used.In addition, the encoding/decoding should specify the charset used, e.g.
initialMessage.getBytes(StandardCharsets.UTF_8)
, otherwise platform dependent default values are applied.Both can lead to incompatibilities between encryption and decryption.