【问题标题】:How to put a KeyPair into a KeyStore the right way? (programmatically in Java)如何以正确的方式将 KeyPair 放入 KeyStore? (在 Java 中以编程方式)
【发布时间】:2021-07-12 12:49:27
【问题描述】:

最好展示我的问题并在之后进行解释(我正在使用 KeyStore Explorer 来查看我的 .pfx 文件):

基本上,我想要右边的结果,但我得到左边的结果。

更准确地说:KeyStore 应该在一个条目中包含私钥和证书链 (KeyPair)。

我不知何故无法让它在 java 中工作。这是我试图在左边得到结果: 下面代码的问题是,它没有验证证书并将它们添加为受信任的证书。

    /**
     * Creates and returns a new {@link KeyStore} from the provided information.
     * @param keystoreType The {@link KeyStore}s type. Recommended: "pkcs12".
     *                     Check {@link KeyStore#getInstance(String)} for details.
     * @param passwordAsCharArray Password to encrypt this {@link KeyStore} and its keys.
     * @param certificateChain The certificate chain is simply an array of {@link X509Certificate}s.
     * @param privateKey The {@link PrivateKey}.
     * @param publicKey The {@link PublicKey}.
     * @throws KeyStoreException
     */
    public KeyStore buildAndGetKeystore(String keystoreType, char[] passwordAsCharArray,
                                        X509Certificate[] certificateChain, PrivateKey privateKey, PublicKey publicKey)
            throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, EmptyStringException, EmptyCharArrayException, EmptyCertificateChainException {

        // Check for null parameters
        Objects.requireNonNull(keystoreType);
        Objects.requireNonNull(passwordAsCharArray);
        Objects.requireNonNull(certificateChain);
        Objects.requireNonNull(privateKey);
        Objects.requireNonNull(publicKey);

        // Check for empty parameters
        if (keystoreType.isEmpty()) throw new EmptyStringException("Parameter 'keystoreType' should NOT be empty!");
        if (passwordAsCharArray.length==0) throw new EmptyCharArrayException("Parameter 'passwordAsCharArray' should NOT be empty!");
        if (certificateChain.length==0) throw new EmptyCertificateChainException("Parameter 'certificateChain' should NOT be empty!");

        // Initialise a new keystore
        KeyStore keystore = KeyStore.getInstance(keystoreType);
        keystore.load(null, passwordAsCharArray); // Pass null to tell java this is a new keystore

        // Insert certificates
        for (int i = 0; i < certificateChain.length; i++) {
            keystore.setCertificateEntry(""+i, certificateChain[i]);
        }

        // Write private key (with password protection) to keystore.
        // NOTE: I tried this before and it only writes 
        // the private key to the .pfx file and ignores the domain chain
        //keystore.setKeyEntry("sso-signing-key", privateKey, passwordAsCharArray, certificateChain);

        return keystore;
    }

一些额外的细节:

右侧的 KeyStore 是这样创建的:首先在 sslforfree.com 生成证书,然后将它们转换为带有 https://decoder.link/converter 的 PKCS12 KeyStore

【问题讨论】:

    标签: java ssl ssl-certificate keystore encryption-asymmetric


    【解决方案1】:

    你们不会相信这一点,但是...问题出在别名“priv-key”上。刚刚删除了连字符“-”并将别名更改为“myKey”,就像在https://stackoverflow.com/a/67147429/13600212 中一样,瞧,它可以工作了...... 这么愚蠢的事情浪费了这么多小时......

    【讨论】:

      【解决方案2】:

      我创建了自己的证书链并将此结构用于证书链:

      X509Certificate[] certificateChain = new X509Certificate[3];
      certificateChain[0] = topCertificate;
      certificateChain[1] = middleCertificate;
      certificateChain[2] = rootCertificate;
      

      密钥库创建部分就像这样简单(我省略了“notNull 检查”):

      KeyStore keystore = KeyStore.getInstance(keystoreType);
      keystore.load(null,null);
      keystore.setKeyEntry("use_your_own_alias", privateKey, passwordAsCharArray, certificateChain);
      return keystore;
      

      请注意,publicKey 不是存储过程的一部分,因为它可用于

      certificateChain[0].getPublicKey()
      

      在 KeyStoreExplorer 中检查密钥库(我使用的是 PKCS12 密钥库)给出以下输出:

      还有钥匙链:

      【讨论】:

      • 没有密码保护密钥库有什么原因吗?
      • 答案很简单——(我在开玩笑!)我为什么要这么做?您的代码假设您想直接“使用”密钥库而不进行存储。 key entry 受给定密码(char 数组)保护,如果您要将密钥库保存在设备上,您将使用一些代码,例如 "keyStore.store(new FileOutputStream(keystore),password );"并使用与密钥输入相同的密码。因此,您问题的“正确”答案是:“它受密钥输入密码保护”:-)
      猜你喜欢
      • 2018-12-23
      • 2022-06-12
      • 1970-01-01
      • 2012-09-12
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多