为什么尽管使用了相同的参数,为什么签名验证不起作用?

发布于 2025-02-13 22:43:14 字数 1769 浏览 1 评论 0原文

我很难进行此简单测试以验证签名工作。我有来自同一密钥店的公共和私钥,我执行了签名和验证的确切步骤,但是验证始终是错误的。

我应该怀疑一些编码问题吗?

@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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝眸 2025-02-20 22:43:15

不,在签名和验证时,您不会执行相同的步骤:使用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 of encrypted is signed. Therefore, when verifying, sign.update(encrypted) has to be used, but instead sign.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文