276

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

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

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

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

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

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

4

9 回答 9

387
  • 如果要进行身份验证,则需要私钥-没有其他选择。
  • 证书是具有额外属性(如公司名称、国家/地区...)的公钥,由某些证书颁发机构签名,以保证附加属性是真实的。
  • .CER文件是证书,没有私钥。私钥.PFX keystore通常随文件提供。如果您真的进行身份验证是因为您已经导入了私钥。
  • 您通常可以.CER毫无问题地导入证书

    keytool -importcert -file certificate.cer -keystore keystore.jks -alias "Alias" 
    
于 2010-12-01T16:10:19.637 回答
124

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

  1. 去你的java_home\jre\lib\security
  2. ( Windows )使用cmdand CTRL++打开管理命令行SHIFTENTER
  3. 运行 keytool 导入证书:
    • (分别替换yourAliasNamepath\to\certificate.cer

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

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

于 2015-01-13T17:43:02.670 回答
61

这是我一直用于以编程方式将 .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);
}
于 2012-09-17T05:49:15.277 回答
24

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

以下对我有用:

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-----
于 2010-12-01T14:53:51.430 回答
17

keystore-explorer.org上提供了一个开源 GUI 工具

密钥库资源管理器

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

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

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

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

在此处输入图像描述

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

如果您提供 google 站点链接,结果窗口将如下所示。 在此处输入图像描述

这是用例之一,其余由用户决定(所有积分都转到keystore-explorer.org

于 2017-11-27T06:41:47.467 回答
8

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

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

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

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

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

于 2010-12-01T16:21:40.457 回答
6

这是我用来将当前目录中的一堆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
于 2017-03-02T18:47:46.607 回答
1

这对我来说是这样的:

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

    -----BEGIN CERTIFICATE----- [微软序列化的数据] -----END CERTIFICATE-----

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

尽管已经提供了很多好的答案,但我想提供一种以编程方式加载 ssl 材料的替代方法。您可以尝试以下代码段:

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 格式的文件。此示例代码片段来自库:GitHub - SSLContext Kickstart您可以使用以下片段添加它:

<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart</artifactId>
    <version>7.0.2</version>
</dependency>
于 2021-10-24T21:28:46.003 回答