当前位置: 首页 > 知识库问答 >
问题:

私钥算法与最终实体证书中的公钥算法不匹配(在索引0处)

花阳辉
2023-03-14

我试图将私钥和it证书链存储在密钥库中,我得到以下错误:私钥算法与最终实体证书中的公钥算法不匹配(在索引0处)

这就是我生成密钥对的方式:

public GenerateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    //Generating and ECDSA KeyPair
    ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime239v3");
    KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");

    g.initialize(ecSpec, new SecureRandom());

    KeyPair keygen = g.generateKeyPair();

    //Setting the ECDSA KeyGen
    this.keygen = keygen;
}

这是我用来生成X509证书的方法:

public static X509Certificate GetCertificate_v3(KeyPair keygen, Date startDate, Date expiryDate, 
        String serial,  String Certification_Aut_Id) throws InvalidKeyException, SecurityException, SignatureException{

    X509V3CertificateGenerator v3CertGen =  new X509V3CertificateGenerator();
    v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
    v3CertGen.setIssuerDN(new X509Principal("CN=" + Certification_Aut_Id + ", O=o, L=L, ST=il, C= c"));
    v3CertGen.setNotBefore(startDate);
    v3CertGen.setNotAfter(expiryDate);
    v3CertGen.setSubjectDN(new X509Principal("CN=" + Certification_Aut_Id + ", O=o, L=L, ST=il, C= c"));
    v3CertGen.setPublicKey(keygen.getPublic());
    v3CertGen.setSignatureAlgorithm("SHA256withECDSA");
    X509Certificate cert = v3CertGen.generateX509Certificate(keygen.getPrivate());

    return cert;

}

用于存储密钥对的代码是:

public static void storeKeypair(String KSpwd, String PKpwd, String KSname, X509Certificate certificate, 
        KeyPair keygen, String alias, String temp_local) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{

    //Before a keystore can be accessed, it must be loaded.
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        // get user password and file input stream
        char[] KSpassword = KSpwd.toCharArray();
        FileInputStream fis = new java.io.FileInputStream(KSname);
        ks.load(fis, KSpassword);
        fis.close();

        //writing the X509Certificate in a .cer file
        FileOutputStream fos1 = new FileOutputStream(temp_local + alias + ".cer");
        fos1.write( certificate.getEncoded() );
        fos1.flush();
        fos1.close();

    // Load the certificate chain (in X.509 DER encoding).
        FileInputStream certificateStream = new FileInputStream(temp_local + alias + ".cer");
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        Certificate[] chain = {};
        chain = certificateFactory.generateCertificates(certificateStream).toArray(chain);

    // save my private key & certificate chain
        char[] PKpassword = PKpwd.toCharArray();
        ks.setEntry(alias, new KeyStore.PrivateKeyEntry(keygen.getPrivate(), chain),
                    new KeyStore.PasswordProtection(PKpassword)
                );

    //Store the KeyStore
     // Write out the keystore
        FileOutputStream fos = new FileOutputStream(KSname);
        ks.store(fos, KSpassword);
        fos.close();
}

生成的错误为:

Exception in thread "main" java.lang.IllegalArgumentException: private key algorithm does not match algorithm of public key in end entity certificate (at index 0)
at java.security.KeyStore$PrivateKeyEntry.<init>(KeyStore.java:408)
at SDSGeneration.keyStore.storeKeypair(keyStore.java:65)
at FinalTest.main(FinalTest.java:70)

共有2个答案

暨高洁
2023-03-14

我在生成乏味的键以启用Web推送时遇到了这个问题。我想将生成的密钥存储到java密钥库中,该密钥库要求您拥有私钥证书。

将算法从ECDSA更改为EC使事情得以进行。Afaik EC是生成密钥的算法,而ECDSA是EC密钥的签名算法。

public static KeyPair generateVapidKeyPair() throws CryptoException {
    try {
        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
        KeyPairGenerator g = KeyPairGenerator.getInstance("EC", "BC");
        g.initialize(ecSpec, new SecureRandom());
        return g.generateKeyPair();
    } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException ex) {
        throw new CryptoException("Could not generate VAPID keypair", ex);
    }
}

之后,我用SHA256with ECDSA算法签署密钥,并用BC生成证书。这与RSA基本相同,所以我将省略这部分代码。之后,我能够毫无问题地从密钥库中存储和检索密钥(以编程方式使用BC作为提供者)。

袁文景
2023-03-14

我在使用Web Crypto API时遇到了同样的问题。我的问题是,我使用密钥对而不是派生的密钥来加密消息。

你可以在这里找到一个完整的例子

 类似资料:
  • 如何验证公钥与私钥匹配? 在应用程序启动时,从base64 PEM编码字符串加载2048位RSA密钥。我希望在继续之前验证密钥是否有效以及是否匹配。签名和验证由我使用的下划线库完成。 我可以签署和验证虚拟数据,但我正在寻找替代解决方案。 首发操场:https://play.golang.org/p/tsB8Yp-xs47

  • a.从存储区提取现有证书密钥: b.从导出的证书中提取私钥: 没有证书与私钥匹配 我错过了什么?为什么我的最后一个命令不合法? 我计划执行“keytool-importkeystore”文件。p12(应该在最后一步中生成)来替换“keystore”中的“一个”privateKeyEntry。正如在如何导入Java keystore中现有的x509证书和私钥以便在SSL中使用中所建议的?。基本上,我

  • 本文向大家介绍基于私钥加密公钥解密的RSA算法C#实现方法,包括了基于私钥加密公钥解密的RSA算法C#实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了基于私钥加密公钥解密的RSA算法C#实现方法,是一种应用十分广泛的算法。分享给大家供大家参考之用。具体方法如下: 一、概述 RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出

  • 问题内容: 我正在寻找一个Java库或代码来即时生成证书,公共和私有密钥,而无需使用第三方程序(例如openssl)。 我认为是从Java代码中获取keytool + openssl的东西。 考虑使用ssl和客户端身份验证保护的基于Java servlet的Web应用程序。我希望Servlet容器仅在请求时使用Java代码生成客户端证书(例如pkcs12格式)。 问题答案: 您可以使用一对或密钥在

  • 因此,我正在通过 SAML2.0 为我们的应用程序实现 SSO。我们正在使用 saml2-js,并且我们正在执行 SP 启动的 SSO。 实现已经准备好了,它正在工作,但是有几个部分我还在纠结。 saml2-js要求您在ServiceProvider实例上提供私钥和证书-

  • 本文向大家介绍获取Android签名证书的公钥和私钥的简单实例,包括了获取Android签名证书的公钥和私钥的简单实例的使用技巧和注意事项,需要的朋友参考一下 本文以Android签名JKS格式的证书为例: 以上这篇获取Android签名证书的公钥和私钥的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。