【问题标题】:How can I generate a key pair and insert it into a KeyStore programmatically (without using the Java KeyTool)?如何生成密钥对并将其以编程方式插入 KeyStore(不使用 Java KeyTool)?
【发布时间】:2017-08-15 20:11:07
【问题描述】:

我想生成一个密钥对并以编程方式将其插入 Java KeyStore。我可以使用命令行来做我想做的事,但是如何使用 Java 代码来做呢?

这里是命令行:

keytool -genkeypair \
    -dname "cn=Unknown" \
    -alias main \
    -keyalg RSA \
    -keysize 4096 \
    -keypass 654321 \
    -keystore C:\\Users\\Felipe\\ks \
    -storepass 123456 \
    -validity 365

这是我目前拥有的 Java 代码:

public static void main(String[] args) {
    try (
        FileOutputStream fos = new FileOutputStream("C:\\Users\\Felipe\\ks");
    ) {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG"));
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        Certificate[] chain = {};

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); // Error: Private key must be accompanied by certificate chain
        keyStore.store(fos, "123456".toCharArray());
    } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) {
        e.printStackTrace();
    }
}

但我不断收到以下错误消息:Private key must be accompanied by certificate chain

我想我应该创建一个证书并将其插入到证书数组中,但是该怎么做呢?

【问题讨论】:

    标签: java keytool


    【解决方案1】:

    这是一个很好的 Java 函数,可以通过编程方式生成自签名证书 (link):

    private X509Certificate generateCertificate(String dn, KeyPair keyPair, int validity, String sigAlgName) throws GeneralSecurityException, IOException {
        PrivateKey privateKey = keyPair.getPrivate();
    
        X509CertInfo info = new X509CertInfo();
    
        Date from = new Date();
        Date to = new Date(from.getTime() + validity * 1000L * 24L * 60L * 60L);
    
        CertificateValidity interval = new CertificateValidity(from, to);
        BigInteger serialNumber = new BigInteger(64, new SecureRandom());
        X500Name owner = new X500Name(dn);
        AlgorithmId sigAlgId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
    
        info.set(X509CertInfo.VALIDITY, interval);
        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
        info.set(X509CertInfo.SUBJECT, owner);
        info.set(X509CertInfo.ISSUER, owner);
        info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
        info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
        info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(sigAlgId));
    
        // Sign the cert to identify the algorithm that's used.
        X509CertImpl certificate = new X509CertImpl(info);
        certificate.sign(privateKey, sigAlgName);
    
        // Update the algorith, and resign.
        sigAlgId = (AlgorithmId) certificate.get(X509CertImpl.SIG_ALG);
        info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, sigAlgId);
        certificate = new X509CertImpl(info);
        certificate.sign(privateKey, sigAlgName);
    
        return certificate;
    }
    

    您可以使用它从您的密钥对生成证书并将其插入证书链中,以使setKeyEntry() 方法起作用:

    public static void main(String[] args) {
        try (
            FileOutputStream fos = new FileOutputStream("C:\\Users\\Felipe\\ks");
        ) {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(4096);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
    
            Certificate[] chain = {generateCertificate("cn=Unknown", keyPair, 365, "SHA256withRSA")};
    
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain);
            keyStore.store(fos, "123456".toCharArray());
        } catch (IOException | GeneralSecurityException e) {
            e.printStackTrace();
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多