【问题标题】:keytool importing multiple certificates in single filekeytool 在单个文件中导入多个证书
【发布时间】:2013-01-17 14:52:00
【问题描述】:

如何使用 keytool [to cert store] 在单个文件中导入多个证书?

keytool -importcert 只导入第一个。

【问题讨论】:

  • 是什么样的文件?

标签: java ssl-certificate


【解决方案1】:

如果您想包含 CA 证书,您应该添加 -trustcacerts 选项。

如果您在一个 PEM 文件中有多个证书链,则必须split the file

【讨论】:

  • 这不是问题 - 我如何从单个文件中添加多个?
【解决方案2】:

我想做同样的事情,但显然只有在您也导入密钥时才有可能:

有两种类型的条目——密钥条目和可信证书条目, 并且只有密钥条目可以包含证书的“链”,附加 给它。受信任的证书条目都是单个证书条目。

(https://www.java.net/node/674524#comment-709695)

我什至尝试过converting to PKCS#7 format first,但没有成功,要么是因为上述原因,要么是因为我的keytool版本太旧。

因此必须先将文件拆分为单独的证书:

cat certchain.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > ("cert" n ".pem")}'

(https://serverfault.com/q/391396/58568)

然后分别导入每一个。

【讨论】:

  • 请注意,要严格正确,您需要在字符串连接周围加上括号:("cert" n ".pem")。没有它们,某些版本的 awk 会变得混乱(OS X,无论如何)。
【解决方案3】:

从 PEM 文件导入所有证书的 bash 脚本:

#!/bin/bash
PEM_FILE=$1
PASSWORD=$2
KEYSTORE=$3
# number of certs in the PEM file
CERTS=$(grep 'END CERTIFICATE' $PEM_FILE| wc -l)

# For every cert in the PEM file, extract it and import into the JKS keystore
# awk command: step 1, if line is in the desired cert, print the line
#              step 2, increment counter when last line of cert is found
for N in $(seq 0 $(($CERTS - 1))); do
  ALIAS="${PEM_FILE%.*}-$N"
  cat $PEM_FILE |
    awk "n==$N { print }; /END CERTIFICATE/ { n++ }" |
    keytool -noprompt -import -trustcacerts \
            -alias $ALIAS -keystore $KEYSTORE -storepass $PASSWORD
done

例如:

./jks_import_pem TrustedCAs.PEM changeit truststore.jks

【讨论】:

    【解决方案4】:

    给出的答案并不是真正的 Ansible 解决方案,更像是替代方案。

    我在下面写的内容适用于第一个证书,但它不是循环的。有什么想法吗?

        java_install_keystore_cert: true
        java_keystore_certs: "{{ apps.jira.keystore_certs }}"
        java_keystore_cert_alias: test
    
    apps:
      jira:
        keystore_certs:
          - certName: xyz.xxx.com
            certFileName: xyz.xxx.com.pem
          - certName: xxx.com
            certFileName: xxx.com.pem
    
    - name: Copy SSL certificate to remote server
      copy:
        src: "{{ java_keystore_certs[0].certFileName }}"
        #src: "{{ java_keystore_cert_file }}"
        dest: /tmp/
      when: java_install_keystore_cert|default(false)
    
    - name: Determine Java cacerts keystore location
      find:
        paths: "{{ java_home }}/"
        patterns: 'cacerts'
        recurse: yes
      register: cacerts_file
      when: java_install_keystore_cert|default(false)
    
    - name: Import SSL certificate to Java cacerts keystore
      java_cert:
        cert_alias: "{{ java_keystore_cert_alias }}"
        #cert_path: "/tmp/{{ java_keystore_cert_file }}"
        cert_path: "/tmp/{{ java_keystore_certs[0].certFileName }}"
        keystore_path: "{{ cacerts_file.files[0].path }}"
        keystore_pass: changeit
        executable: "{{ java_home }}/bin/keytool"
        state: present
      when: java_install_keystore_cert|default(false) and cacerts_file is defined
    

    【讨论】:

      【解决方案5】:

      我还切换到了一个不仅仅是 Ansible 解决方案....

        copy:
          src: "{{ java_keystore_cert_file }}"
          dest: /tmp/
        when: java_install_keystore_cert|default(false)
      
      - name: Determine Java keystore (cacerts) location
        find:
          paths: "{{ java_home }}/"
          patterns: 'cacerts'
          recurse: yes
        register: cacerts_file
        when: java_install_keystore_cert|default(false)
      
      # Not using the java_cert module (anymore) since that imports the first certificate only
      
      # Always use .pem (simply rename .crt or .cert to .pem if needed)
      # The .pem file should contain one or more public certificates, no private key(s) or chain
      - name: Transfer the import certificate script
        copy:
          src: files/scripts/importcert.sh
          dest: /tmp/importcert.sh
          mode: 0700
        when: java_install_keystore_cert|default(false) and cacerts_file is defined
      
      - name: Import certificate to Java keystore
        command: sh /tmp/importcert.sh "/tmp/{{ java_keystore_cert_file }}" "{{ java_home }}/bin/keytool" changeit "{{ cacerts_file.files[0].path }}"
        when: java_install_keystore_cert|default(false) and cacerts_file is defined
      
      #!/bin/bash
      PEM_FILE=$1
      KEYTOOL=$2
      PASSWORD=$3
      KEYSTORE=$4
      # number of certs in the PEM file
      CERTS=$(grep 'END CERTIFICATE' $PEM_FILE| wc -l)
      
      # For every cert in the PEM file, extract it and import into the JKS keystore
      # awk command: step 1, if line is in the desired cert, print the line
      #              step 2, increment counter when last line of cert is found
      for N in $(seq 0 $(($CERTS - 1))); do
        ALIAS="${PEM_FILE%.*}-$N"
        cat $PEM_FILE |
          awk "n==$N { print }; /END CERTIFICATE/ { n++ }" |
          $KEYTOOL -noprompt -import -trustcacerts \
                  -alias $ALIAS -keystore $KEYSTORE -storepass $PASSWORD
      done
      

      【讨论】:

        【解决方案6】:

        您可以使用 p11-kit 工具快速完成此操作。 唯一的限制是它从 /etc/pki/ca-trust/source/ 读取证书

        /usr/bin/p11-kit extract --format=java-cacerts --filter=ca-anchors \
                        --overwrite --purpose server-auth $DEST/java/cacerts
        

        【讨论】:

          【解决方案7】:

          您可以简单地使用免费且易于使用的 GUI 工具 Keystore Explorer 导入和管理多个证书。

          【讨论】:

            猜你喜欢
            • 2014-06-05
            • 2018-04-18
            • 2014-03-01
            • 2020-03-26
            • 1970-01-01
            • 2013-03-28
            • 1970-01-01
            • 2012-05-06
            • 1970-01-01
            相关资源
            最近更新 更多