You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从CloudHSM密钥库取密钥对生成CSR时遇UnsupportedOperationException问题求助

问题:从CloudHsm密钥库取出私钥生成CSR时抛出getPrivateExponent不支持异常

从CloudHsmProvider的密钥库中获取密钥对后,使用BouncyCastle生成证书签名请求(CSR)时,抛出异常:

java.lang.UnsupportedOperationException: getPrivateExponent is not supported by CloudHsmRsaPrivateCrtKey

但如果直接生成密钥对后不存入密钥库,直接用于生成CSR则无此错误,且能正常生成预期的CSR文件。请问该问题是否由密钥对保存到密钥库时的操作错误导致?

生成CSR的代码

public static void main(String[] args) {
    try {
        try {
            if (Security.getProvider(CloudHsmProvider.PROVIDER_NAME) == null) {
                Security.addProvider(new CloudHsmProvider());
            }
        } catch (IOException ex) {
            System.out.println(ex);
            return;
        }
        String keystoreFile = "abc.p12";
        String password = "123456";
        String label = "tuan14";

        final String privateLabel = label + ":Private";

        final KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.CLOUDHSM_KEYSTORE_TYPE);
        try {
            final FileInputStream instream = new FileInputStream(keystoreFile);
            keyStore.load(instream, password.toCharArray());
        } catch (final FileNotFoundException ex) {
            System.err.println("Keystore not found, loading an empty store");
            keyStore.load(null, null);
        }

        final PasswordProtection passwordProtection = new PasswordProtection(password.toCharArray());
        System.out.println("Searching for example key pair and certificate...");

        final PrivateKeyEntry keyEntry =
            (PrivateKeyEntry) keyStore.getEntry(privateLabel, passwordProtection);
        final String name = keyEntry.getCertificate().toString();
        System.out.printf("Found private key %s with certificate %s%n", label, name);

        PublicKey publicKey = keyEntry.getCertificate().getPublicKey();
        PrivateKey privateKey = keyEntry.getPrivateKey();

        X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);

        x500NameBld.addRDN(BCStyle.CN, "ABC");
        x500NameBld.addRDN(BCStyle.C, "Viet Nam");
        x500NameBld.addRDN(BCStyle.ST, "Hà nội");
        x500NameBld.addRDN(BCStyle.L, "Cầu Giấy");
        x500NameBld.addRDN(BCStyle.O, "ABC");
        x500NameBld.addRDN(BCStyle.OU, "ABC");
        x500NameBld.addRDN(BCStyle.UID, "1427732196");
        x500NameBld.addRDN(BCStyle.UID, "1427732189");
        x500NameBld.addRDN(BCStyle.TELEPHONE_NUMBER, "0339028712");
        x500NameBld.addRDN(BCStyle.EmailAddress, "tuanpa1232321@gmail.com");
        x500NameBld.addRDN(BCStyle.STREET, "abc");
        X500Name subject = x500NameBld.build();

        PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
                subject, publicKey);
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");

        ContentSigner signer = csBuilder.build((PrivateKey) privateKey);
        PKCS10CertificationRequest csr = p10Builder.build(signer);
        PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());

        StringWriter strWriter;
        try (JcaPEMWriter pemWriter = new JcaPEMWriter(strWriter = new StringWriter())) {
            pemWriter.writeObject(pemObject);
        }
        writeToFile(strWriter.toString().getBytes(), "demo.pem");

    } catch (Throwable thr) {
        thr.printStackTrace();
        System.out.println("HSM Exception printStackTrace():");
    }
}

存储密钥对的代码

private static X509Certificate generateCertificate(String dn, String issuer, KeyPair pair, int days,
        String algorithm) throws GeneralSecurityException, IOException {
    PrivateKey privkey = pair.getPrivate();
    X509CertInfo info = new X509CertInfo();
    Date from = new Date();
    Date to = new Date(from.getTime() + days * 86400000l);
    CertificateValidity interval = new CertificateValidity(from, to);
    BigInteger sn = new BigInteger(64, new SecureRandom());
    X500Name owner = new X500Name(dn);
    X500Name issuerName = new X500Name(issuer);
    AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
    if ("1.8".equals(System.getProperty("java.specification.version"))) {
        info.set(X509CertInfo.VALIDITY, interval);
        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
        info.set(X509CertInfo.SUBJECT, owner); 
        info.set(X509CertInfo.ISSUER, issuerName);
        info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
        info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
        info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
    }
    X509CertImpl cert = new X509CertImpl(info);
    cert.sign(privkey, algorithm);
    algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG);
    info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
    cert = new X509CertImpl(info);
    cert.sign(privkey, algorithm);
    return cert;
}

public static void main(String[] args) {
    try {
        try {
            if (Security.getProvider(CloudHsmProvider.PROVIDER_NAME) == null) {
                Security.addProvider(new CloudHsmProvider());
            }
        } catch (IOException ex) {
            System.out.println(ex);
            return;
        }

        String password = "123456";
        String label = "tuan14";
        String keystoreFile = "./abc.p12";

        String privateLabel = label+":Private";
        final PasswordProtection passwordProtection =
        new PasswordProtection(password.toCharArray());

        KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.CLOUDHSM_KEYSTORE_TYPE);
        keyStore.load(null, password.toCharArray());
        final KeyAttributesMap requiredPublicKeyAttributes =
            new KeyAttributesMapBuilder().put(KeyAttribute.VERIFY, true).build();
        final KeyAttributesMap requiredPrivateKeyAttributes =
            new KeyAttributesMapBuilder().put(KeyAttribute.SIGN, true).build();
        final KeyPair keyPair =
            AsymmetricKeys.generateRSAKeyPair(
                2048, label, requiredPublicKeyAttributes, requiredPrivateKeyAttributes);
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        System.out.println("Keypair info: ");
        System.out.println("Private key: " + privateKey.toString());
        System.out.println("Public key: " + publicKey);
        System.out.println("Algo PrivateKey: " + privateKey.getAlgorithm());
        X509Certificate rootCertificate = generateCertificate(
        "CN="+label,
        "CN="+label,
        keyPair, 
        30, 
        "SHA256WithRSA");

        //Create Chain
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = rootCertificate;
        final PrivateKeyEntry entry = new PrivateKeyEntry(keyPair.getPrivate(), chain);
        keyStore.setEntry(privateLabel, entry, passwordProtection);

        final FileOutputStream outstream = new FileOutputStream(keystoreFile);
        keyStore.store(outstream, password.toCharArray());
        outstream.close();
    } catch (Throwable thr) {
        thr.printStackTrace();
        System.out.println("HSM Exception printStackTrace():");
    }
}

public static KeyPair generateRSAKeyPair(
        int keySizeInBits,
        String label,
        KeyAttributesMap additionalPublicKeyAttributes,
        KeyAttributesMap additionalPrivateKeyAttributes)
        throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
                NoSuchProviderException, AddAttributeException {
    KeyPairGenerator keyPairGen =
            KeyPairGenerator.getInstance("RSA", CloudHsmProvider.PROVIDER_NAME);
    final KeyAttributesMap publicKeyAttrsMap = new KeyAttributesMap();
    publicKeyAttrsMap.putAll(additionalPublicKeyAttributes);
    publicKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Public");
    publicKeyAttrsMap.put(KeyAttribute.MODULUS_BITS, keySizeInBits);
    publicKeyAttrsMap.put(KeyAttribute.PUBLIC_EXPONENT, new BigInteger("65537").toByteArray());

    final KeyAttributesMap privateKeyAttrsMap = new KeyAttributesMap();
    privateKeyAttrsMap.putAll(additionalPrivateKeyAttributes);
    privateKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Private");

    KeyPairAttributesMap keyPairSpec =
            new KeyPairAttributesMapBuilder()
                    .withPublic(publicKeyAttrsMap)
                    .withPrivate(privateKeyAttrsMap)
                    .build();

    keyPairGen.initialize(keyPairSpec);
    return keyPairGen.generateKeyPair();
}

内容的提问来源于stack exchange,提问作者Pham Anh Tuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:15:42