【问题标题】:Could not verify SHA1 signature with RSA无法使用 RSA 验证 SHA1 签名
【发布时间】:2017-07-30 23:31:20
【问题描述】:

我正在尝试验证 Java 中的证书签名,但它失败了。我猜SHA1 和 SHA1withRSA 之间存在差异,但我该如何解决呢?

这是使用 C# 登录的代码(证书为 mycer.p12):

static string Sign(string token, string cer_name, string passw)
        {
            try
            {
                if (!File.Exists(cer_name))
                {
                    MessageBox.Show("File not found " + cer_name);
                    return "";
                }
                X509Certificate2 cert = new X509Certificate2(cer_name, passw, X509KeyStorageFlags.Exportable);
                RSACryptoServiceProvider csp = null;
                csp = (RSACryptoServiceProvider)cert.PrivateKey;
                if (csp == null)
                {
                    MessageBox.Show("No valid cert was found");
                    return "";
                }
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                byte[] data = encoding.GetBytes(token);
                RSACryptoServiceProvider rsaClear = new RSACryptoServiceProvider();
                rsaClear.ImportParameters(csp.ExportParameters(true));
                byte[] signature = rsaClear.SignData(data, CryptoConfig.MapNameToOID("SHA1"));
                bool isValid = csp.VerifyData(data, "SHA1", signature);
                if (isValid) return Convert.ToBase64String(signature).Trim(new char[] { '\0', '\n' }).Replace("\n", "");
                else
                {
                    MessageBox.Show("Siganture verification = FALSE");
                    return "";
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return "";
            }
        }

我使用这个命令来提取公钥

openssl pkcs12 -in mycer.p12 -clcerts -nokeys -out publicKEY.pem

现在这段代码在 Java 中进行验证,但它返回 false:

 public static boolean verify(String plainText, String signature, String publicKeyFile) {
            try {
CertificateFactory f = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate)f.generateCertificate(new FileInputStream(publicKeyFile));
                Signature publicSignature = Signature.getInstance("SHA1withRSA");
                publicSignature.initVerify(publicKey);
                publicSignature.update(plainText.getBytes("UTF-8"));
                byte[] signatureBytes = Base64.decode(signature);
                return publicSignature.verify(signatureBytes);
            } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | UnsupportedEncodingException e) {
                e.printStackTrace();
                return false;
            }
        }

【问题讨论】:

  • 在这里返回 false publicSignature.verify(signatureBytes); 或在异常 e.printStackTrace(); return false; 之后?在第二种情况下,发布完整的堆栈跟踪。还要查看 publicKeyFile 仅包含一个证书
  • 这里返回 false publicSignature.verify(signatureBytes);我会尝试不同的证书。
  • 与其他证书相同:/

标签: java c# x509certificate sha1


【解决方案1】:

这篇文章帮助了我https://stackoverflow.com/a/16980246/1444413

KeyStore p12 = KeyStore.getInstance("pkcs12");
p12.load(new FileInputStream("mycer.p12"), "password".toCharArray());
String alias = (String) p12.aliases().nextElement();
X509Certificate c = (X509Certificate) p12.getCertificate(alias);
.... c.getPublicKey() ....

然后方法verify()..返回true。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2017-01-14
    相关资源
    最近更新 更多