【问题标题】:How to import a .cer certificate into a java keystore?如何将 .cer 证书导入 java 密钥库?
【发布时间】:2011-05-18 12:54:09
【问题描述】:

在开发 Java Web 服务客户端期间,我遇到了一个问题。 Web 服务的身份验证使用客户端证书、用户名和密码。我从 Web 服务背后的公司收到的客户端证书是 .cer 格式。当我使用文本编辑器检查文件时,它具有以下内容:

-----BEGIN CERTIFICATE-----
[Some base64 encoded data]
-----END CERTIFICATE-----

我可以在 Internet Explorer 中将此文件作为证书导入(无需输入密码!)并使用它来验证网络服务。

我能够通过首先剥离第一行和最后一行、转换为 unix 换行符并运行 base64-decode 来将此证书导入密钥库。生成的文件可以导入到密钥库中(使用keytool 命令)。当我列出密钥库中的条目时,该条目的类型为trustedCertEntry。由于此条目类型 (?),我无法使用此证书对 Web 服务进行身份验证。我开始认为提供的证书是用于身份验证的公共证书...

我发现的一种解决方法是在 IE 中导入证书并将其导出为.pfx 文件。该文件可以作为密钥库加载,并可用于向 Web 服务进行身份验证。但是,我不能指望我的客户每次收到新证书时都执行这些步骤。所以我想将.cer 文件直接加载到Java 中。有什么想法吗?

附加信息:网络服务背后的公司告诉我,应该向 PC 和稍后导入证书的用户请求证书(使用 IE 和网站)。

【问题讨论】:

    标签: java certificate keystore


    【解决方案1】:
    • 如果要进行身份验证,则需要私钥 - 没有其他选择。
    • 证书是具有额外属性(如公司名称、国家/地区...)的公钥,由确保附加属性真实的某些证书​​颁发机构签署。
    • .CER 文件是证书,没有私钥。私钥通常与.PFX keystore 文件一起提供。 如果你真的认证是因为你已经导入了私钥。
    • 您通常可以导入.CER 证书而不会出现任何问题

      keytool -importcert -file certificate.cer -keystore keystore.jks -alias "Alias" 
      

    【讨论】:

    • 原来私钥是由 IE 插件生成的。目前唯一的解决方案是在 IE 中导入证书并导出 .pfx 文件。
    • .CER 文件确实有公钥。他们没有私钥。建议编辑..
    • -alias 在这里做什么?
    • :( --> keytool error: java.lang.Exception: Input not an X.509 certificate
    • @hop 一个 java 密钥库可以有多个证书,每个证书都有一个不同的别名来标识它。您可以使用它作为参考来识别它和/或通过别名以编程方式检索它。
    【解决方案2】:

    将从浏览器下载的.cer 证书文件(打开网址并挖掘详细信息)导入java_home\jre\lib\security 中的 cacerts 密钥库对我有用,而不是尝试生成和使用我自己的密钥库.

    1. 转到您的java_home\jre\lib\security
    2. (Windows) 使用 cmdCTRL+SHIFT+ENTER 打开管理命令行
    3. 运行keytool导入证书:
      • (分别替换yourAliasNamepath\to\certificate.cer

     ..\..\bin\keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourAliasName -file path\to\certificate.cer
    

    这样您不必指定任何额外的 JVM 选项,并且证书应该被 JRE 识别。

    【讨论】:

    • 路径\到\证书。如果我的文件在桌面上,我该如何路径? C:/user/desktop/ 或 ../../../../desktop/filename
    • 在 MacOS /Linux 上,此命令适用于 sudo。谢谢。但什么是 noprompt 参数?我没用过,还是成功了。
    • 注意,使用JDK进行开发时,正确的路径是java_home\jdk_x.xx\jre\lib\security,绝对路径使用反斜杠,例如"C:\myCert.crt" 如果路径不包含空格,则引号是可选的。
    • 感谢一百万次。
    • 问题:私钥呢?讨论是关于客户端证书的。我的理解是,需要使用私钥创建一个 CSR,然后从远程网站公司接收客户端证书,然后将客户端证书与私钥匹配。您的回答似乎没有提及有关私钥的任何内容。只是问问。
    【解决方案3】:

    这是我一直用于以编程方式将 .cer 文件导入新 KeyStore 的代码。

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    //VERY IMPORTANT.  SOME OF THESE EXIST IN MORE THAN ONE PACKAGE!
    import java.security.GeneralSecurityException;
    import java.security.KeyStore;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateFactory;
    
    //Put everything after here in your function.
    KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(null);//Make an empty store
    InputStream fis = /* insert your file path here */;
    BufferedInputStream bis = new BufferedInputStream(fis);
    
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    
    while (bis.available() > 0) {
        Certificate cert = cf.generateCertificate(bis);
        trustStore.setCertificateEntry("fiddler"+bis.available(), cert);
    }
    

    【讨论】:

      【解决方案4】:

      您不必对证书进行任何更改。您确定您正在运行正确的导入命令吗?

      以下对我有用:

      keytool -import -alias joe -file mycert.cer -keystore mycerts -storepass changeit
      

      mycert.cer 包含的位置:

      -----BEGIN CERTIFICATE-----
      MIIFUTCCBDmgAwIBAgIHK4FgDiVqczANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
      BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
      ...
      RLJKd+SjxhLMD2pznKxC/Ztkkcoxaw9u0zVPOPrUtsE/X68Vmv6AEHJ+lWnUaWlf
      zLpfMEvelFPYH4NT9mV5wuQ1Pgurf/ydBhPizc0uOCvd6UddJS5rPfVWnuFkgQOk
      WmD+yvuojwsL38LPbtrC8SZgPKT3grnLwKu18nm3UN2isuciKPF2spNEFnmCUWDc
      MMicbud3twMSO6Zbm3lx6CToNFzP
      -----END CERTIFICATE-----
      

      【讨论】:

      • 当我尝试将未修改的证书导入密钥库时,我收到错误“keytool error: java.lang.Exception: Input not an X.509 certificate”。按照我在帖子中描述的方式修改证书后,我可以使用类似于您的命令导入证书而不会出错。但是,它作为trustedCertEntry 导入,在访问网络服务时不使用。
      • 您能否将命令例外添加到问题中?您确定要在导入命令中指定别名吗?
      • 如果您使用的是 Windows,请不要忘记以管理员身份运行 cmd
      【解决方案5】:

      keystore-explorer.org 提供开源 GUI 工具

      KeyStore 浏览器

      KeyStore Explorer 是 Java 的开源 GUI 替代品 命令行实用程序 keytool 和 jarsigner。密钥库资源管理器 通过直观的图形展示其功能等 用户界面。

      以下屏幕会有所帮助(它们来自官方网站)

      通过运行命令获得的默认屏幕:

      shantha@shantha:~$./Downloads/kse-521/kse.sh
      

      然后转到ExamineExamine a URL 选项,然后提供您要导入的网址。

      如果您提供谷歌站点链接,结果窗口将如下所示。

      这是用例之一,其余由用户决定(所有学分归keystore-explorer.org

      【讨论】:

      • 讽刺的是,提供的链接指向一个未经认证的 http - no s - 站点。
      • @MartinMeeser,该网站是他们的官方网站,我的建议是在您引用它时不要分享任何敏感或个人信息。
      【解决方案6】:

      您已经拥有的证书可能是服务器的证书,或者是用于签署服务器证书的证书。您将需要它,以便您的 Web 服务客户端可以对服务器进行身份验证。

      但如果您还需要使用 SSL 执行客户端身份验证,那么您需要获取自己的证书,以验证您的 Web 服务客户端。为此,您需要创建一个证书请求;该过程涉及创建您自己的私钥和相应的公钥,并将该公钥连同您的一些信息(电子邮件、姓名、域名等)附加到称为证书请求的文件中。然后,您将该证书请求发送给已经要求您提供该证书的公司,他们将创建您的证书,方法是使用他们的私钥签署您的公钥,然后他们会将带有您的证书的 X509 文件发回给您,您可以现在添加到您的密钥库,您就可以使用需要客户端身份验证的 SSL 连接到 Web 服务了。

      要生成您的证书请求,请使用“keytool -certreq -alias -file -keypass -keystore”。将生成的文件发送给将要签署它的公司。

      当您取回证书后,运行“keytool -importcert -alias -keypass -keystore”。

      如果密钥库受到保护,您可能需要在这两种情况下都使用 -storepass(这是个好主意)。

      【讨论】:

        【解决方案7】:

        这是我用来将当前目录中的一堆crt文件批量导入java keystore的脚本。只需将其保存到与您的证书相同的文件夹中,然后像这样运行它:

        ./import_all_certs.sh
        

        import_all_certs.sh

        KEYSTORE="$(/usr/libexec/java_home)/jre/lib/security/cacerts";
        
        function running_as_root()
        {
          if [ "$EUID" -ne 0 ]
            then echo "NO"
            exit
          fi
        
          echo "YES"
        }
        
        function import_certs_to_java_keystore
        {
          for crt in *.crt; do 
            echo prepping $crt 
            keytool -import -file $crt -storepass changeit -noprompt --alias alias__${crt} -keystore $KEYSTORE
            echo 
          done
        }
        
        if [ "$(running_as_root)" == "YES" ]
        then
          import_certs_to_java_keystore
        else
          echo "This script needs to be run as root!"
        fi
        

        【讨论】:

          【解决方案8】:

          这对我来说是这样的:

          1. 在文本编辑器中以以下格式将证书数据另存为 .txt

            -----开始证书----- [微软序列化的数据] -----结束证书-----

          2. 打开 chrome 浏览器(此步骤可能也适用于其他浏览器) 设置 > 显示高级设置 > HTTPS/SSL > 管理证书 在步骤 1 中导入 .txt
          3. 选择并以 Base-64 编码格式导出该证书。将其另存为 .cer
          4. 现在您可以使用 keytool 或 Portecle 将其导入您的 java 密钥库

          【讨论】:

            【解决方案9】:

            虽然已经提供了很多好的答案,但我想提供一种以编程方式加载 ssl 材料的替代方法。你可以试试下面的sn-p:

            Path certificatePath = Paths.get("/path/to/certificate.cer");
            List<Certificate> certificates = CertificateUtils.loadCertificate(certificatePath);
            
            SSLFactory sslFactory = SSLFactory.builder()
                    .withTrustMaterial(certificates)
                    .build();
            
            SSLContext sslContext = sslFactory.getSslContext();
            

            它可以处理 pem、der(二进制)和 p7b 格式的文件。此示例代码 sn-p 来自库:GitHub - SSLContext Kickstart 您可以使用以下 sn-p 添加它:

            <dependency>
                <groupId>io.github.hakky54</groupId>
                <artifactId>sslcontext-kickstart</artifactId>
                <version>7.0.2</version>
            </dependency>
            

            【讨论】:

              猜你喜欢
              • 2013-07-11
              • 1970-01-01
              • 2017-10-25
              • 1970-01-01
              • 2013-01-02
              • 2014-02-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多