如何使用 ApacheHttpClient 处理无效的 SSL 证书?

我知道,关于这个问题有很多不同的问题和很多答案... 但是我不能理解..。

我有: ubuntu-9.10-桌面-amd64 + NetBeans6.7.1从 off. rep“ as is”安装。 我需要通过 HTTPS 连接到一些站点,为此我使用 Apache 的 HttpClient。

从教程中我读到:

”一旦正确安装了 JSSE,通过 SSL 的安全 HTTP 通信应该如下所示
简单得就像普通的 HTTP 通信一样。”下面是一些例子:

HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}

到现在为止,我这样写道:

HttpClient client = new HttpClient();


HttpMethod get = new GetMethod("https://mms.nw.ru");
//get.setDoAuthentication(true);


try {
int status = client.executeMethod(get);
System.out.println(status);


BufferedInputStream is = new BufferedInputStream(get.getResponseBodyAsStream());
int r=0;byte[] buf = new byte[10];
while((r = is.read(buf)) > 0) {
System.out.write(buf,0,r);
}


} catch(Exception ex) {
ex.printStackTrace();
}

结果,我出现了一系列错误:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1627)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:204)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:198)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:994)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:142)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:533)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:471)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:904)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1132)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:643)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at simpleapachehttp.Main.main(Main.java:41)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:302)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:205)
at sun.security.validator.Validator.validate(Validator.java:235)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:973)
... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:191)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:297)
... 23 more

要创建最简单的 SSL 连接,我需要做什么? (可能没有 KeyManager 和 Trust Manager 等等)

359982 次浏览

Https://mms.nw.ru 相当可能使用非核证机关发出的证书。因此,您需要将证书添加到您的可信 Java 密钥存储区,如 无法找到所请求目标的有效证书路径所述:

当为客户工作时 启用 SSL 的服务器运行在 Https 协议,您可能会得到错误 无法找到有效的证明 路径到请求的目标’,如果 服务器证书不是由 认证机构,但自我 由私人 CMS 签署或签发。

别慌,你只需要 将服务器证书添加到 可信 Java 密钥存储库,如果您的客户端 是用 Java 写的,你可能是 想知道如果你不能访问 服务器所在的机器 有一个简单的程序 可以帮助你,请下载 程序 并运行

% java InstallCert _web_site_hostname_

这个程序打开了一个到 并启动一个 SSL 握手,打印出了异常 发生错误的堆栈跟踪 并向您显示 现在它提示您添加 证书到您信任的 KeyStore。

如果你改变主意了,请进 如果您真的想要添加 证书,请输入「1」或其他 用于添加其他证书的数字, 甚至一个 CA 证书,但你通常 我不想这么做,一旦你 做出了你的选择,程序将 显示完整的证书及 然后将其添加到名为 “ jsseccerts” 目录。

在程序中使用它 将 JSSE 配置为使用它作为其信任 存储或复制到您的 $JAVA _ HOME/jre/lib/security 目录。 如果您希望所有 Java 应用程序 将证书识别为受信任证书 不仅仅是 JSSE,你还可以 覆盖那个文件 目录。

在所有这些之后,JSSE 将能够 完成与主人的握手, 您可以通过运行 程序。

要了解更多细节,可以查看 利兰的博客没有更多的“无法找到” 请求的有效证书路径 目标’

Https://mms.nw.ru 使用不在默认信任管理器集中的自签名证书。要解决此问题,请执行下列操作之一:

  • 使用接受任何证书的 TrustManager配置 SSLContext(见下文)。
  • 使用包含证书的适当信任存储区配置 SSLContext
  • 将该站点的证书添加到默认的 Java 信任存储区。

这里有一个程序,它创建了一个可以接受任何证书的 SSL 上下文(几乎没有价值) :

import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class SSLTest {
    

public static void main(String [] args) throws Exception {
// configure the SSLContext with a TrustManager
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);


URL url = new URL("https://mms.nw.ru");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
System.out.println(conn.getResponseCode());
conn.disconnect();
}
    

private static class DefaultTrustManager implements X509TrustManager {


@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}


@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}


@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}

翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳 http://hc.apache.org/httpclient-3.x/sslguide.html

Protocol.registerProtocol("https",
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}

其中 MySSLSocketFactory 示例可以找到 给你。它引用了一个 TrustManager,您可以修改它来信任所有内容(尽管您必须考虑这一点!)

一旦有了 Java 证书存储(通过使用上面创建的 很好 InstallCert 类) ,就可以通过传递“ javax.net。在 java 启动时使用“ ssl.trust Store”参数。

例如:

java -Djavax.net.ssl.trustStore=/path/to/jssecacerts MyClassName

自签名测试证书可能遇到的另一个问题是:

例外: HTTPS 主机名错误: 应该是..。

试图访问 HTTPS URL 时发生此错误。您可能已经将服务器证书安装到了 JRE 的密钥存储库中。但是这个错误意味着服务器证书的名称与 URL 中提到的服务器的实际域名不匹配。这通常发生在使用非 CA 颁发的证书时。

此示例演示如何编写忽略证书服务器名称的 HttpsURLConnection DefaultHostnameVerifier:

Http://www.java-samples.com/showtutorial.php?tutorialid=211

使用 InstallCert生成 jssecacerts文件并执行 -Djavax.net.ssl.trustStore=/path/to/jssecacerts运行良好。

要想方便地在运行时添加您信任的主机,而不用抛出所有检查,请尝试这里的代码: http://code.google.com/p/self-signed-cert-trust-manager/

这个 链接解释了你所需要的一步一步。如果您并不真正关心可以在下面的链接中继续进行该过程的证书。

注意: 您可能需要再次检查您正在执行的操作,因为这是一个不安全的操作。

除了 Pascal Thient 的正确答案之外,另一种方法是从 Firefox (查看证书-> 详细信息-> 导出)或 openssl s_client中保存证书,并将其导入到信任存储中。

只有在有办法验证证书的情况下才应该这样做。如果没有这样做,那么在第一次连接时执行此操作,如果在后续连接上证书发生意外更改,那么它至少会给出一个错误。

若要在信任存储区中导入它,请使用:

keytool -importcert -keystore truststore.jks -file servercert.pem

默认情况下,默认的信任存储区应该是 $JAVA_HOME/jre/lib/security/cacerts,其密码应该是 changeit,有关详细信息,请参阅 JSSE 参考指南

如果您不希望全局地允许该证书,但只允许这些连接,那么可以为它创建一个 SSLContext:

TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("/.../truststore.jks");
ks.load(fis, null);
// or ks.load(fis, "thepassword".toCharArray());
fis.close();


tmf.init(ks);


SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

然后,您需要为 Apache HTTP Client 3.x 设置它,如果它的 SecureProtocolSocketFactory要使用这个 SSLContext,则需要实现一个。(有例子 给你)。

Apache HTTP Client 4.x (不包括最早的版本)直接支持传递 SSLContext

Apache HttpClient 4.5方式:

org.apache.http.ssl.SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
sslContextBuilder.loadTrustMaterial(new org.apache.http.conn.ssl.TrustSelfSignedStrategy());
SSLContext sslContext = sslContextBuilder.build();
org.apache.http.conn.ssl.SSLConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(sslContext, new org.apache.http.conn.ssl.DefaultHostnameVerifier());


HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslSocketFactory);
httpClient = httpClientBuilder.build();

注意: org.apache.http.conn.ssl.SSLContextBuilder不赞成,而 org.apache.http.ssl.SSLContextBuilder是新的 org.apache.http.ssl.SSLContextBuilder(请注意,后者的软件包名称中缺少 conn)。

我使用的是 httpclient 3.1.X,这对我很有用

        try {
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}


@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {


}


@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[]{trustManager}, null);
SslContextSecureProtocolSocketFactory socketFactory = new SslContextSecureProtocolSocketFactory(sslContext,false);
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) socketFactory, 443));//同样会影响到HttpUtils
} catch (Throwable e) {
e.printStackTrace();

}

public class SslContextSecureProtocolSocketFactory implements      SecureProtocolSocketFactory {


private SSLContext sslContext;
private boolean verifyHostname;


public SslContextSecureProtocolSocketFactory(SSLContext sslContext, boolean verifyHostname) {
this.verifyHostname = true;
this.sslContext = sslContext;
this.verifyHostname = verifyHostname;
}


public SslContextSecureProtocolSocketFactory(SSLContext sslContext) {
this(sslContext, true);
}


public SslContextSecureProtocolSocketFactory(boolean verifyHostname) {
this((SSLContext)null, verifyHostname);
}


public SslContextSecureProtocolSocketFactory() {
this((SSLContext)null, true);
}


public synchronized void setHostnameVerification(boolean verifyHostname) {
this.verifyHostname = verifyHostname;
}


public synchronized boolean getHostnameVerification() {
return this.verifyHostname;
}


public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
SSLSocketFactory sf = this.getSslSocketFactory();
SSLSocket sslSocket = (SSLSocket)sf.createSocket(host, port, clientHost, clientPort);
this.verifyHostname(sslSocket);
return sslSocket;
}


public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
if(params == null) {
throw new IllegalArgumentException("Parameters may not be null");
} else {
int timeout = params.getConnectionTimeout();
Socket socket = null;
SSLSocketFactory socketfactory = this.getSslSocketFactory();
if(timeout == 0) {
socket = socketfactory.createSocket(host, port, localAddress, localPort);
} else {
socket = socketfactory.createSocket();
InetSocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
InetSocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
}


this.verifyHostname((SSLSocket)socket);
return socket;
}
}


public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
SSLSocketFactory sf = this.getSslSocketFactory();
SSLSocket sslSocket = (SSLSocket)sf.createSocket(host, port);
this.verifyHostname(sslSocket);
return sslSocket;
}


public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
SSLSocketFactory sf = this.getSslSocketFactory();
SSLSocket sslSocket = (SSLSocket)sf.createSocket(socket, host, port, autoClose);
this.verifyHostname(sslSocket);
return sslSocket;
}


private void verifyHostname(SSLSocket socket) throws SSLPeerUnverifiedException, UnknownHostException {
synchronized(this) {
if(!this.verifyHostname) {
return;
}
}


SSLSession session = socket.getSession();
String hostname = session.getPeerHost();


try {
InetAddress.getByName(hostname);
} catch (UnknownHostException var10) {
throw new UnknownHostException("Could not resolve SSL sessions server hostname: " + hostname);
}


X509Certificate[] certs = (X509Certificate[])((X509Certificate[])session.getPeerCertificates());
if(certs != null && certs.length != 0) {
X500Principal subjectDN = certs[0].getSubjectX500Principal();
List cns = this.getCNs(subjectDN);
boolean foundHostName = false;
Iterator i$ = cns.iterator();
AntPathMatcher matcher  = new AntPathMatcher();
while(i$.hasNext()) {
String cn = (String)i$.next();
if(matcher.match(cn.toLowerCase(),hostname.toLowerCase())) {
foundHostName = true;
break;
}
}


if(!foundHostName) {
throw new SSLPeerUnverifiedException("HTTPS hostname invalid: expected \'" + hostname + "\', received \'" + cns + "\'");
}
} else {
throw new SSLPeerUnverifiedException("No server certificates found!");
}
}


private List<String> getCNs(X500Principal subjectDN) {
ArrayList cns = new ArrayList();
StringTokenizer st = new StringTokenizer(subjectDN.getName(), ",");


while(st.hasMoreTokens()) {
String cnField = st.nextToken();
if(cnField.startsWith("CN=")) {
cns.add(cnField.substring(3));
}
}


return cns;
}


protected SSLSocketFactory getSslSocketFactory() {
SSLSocketFactory sslSocketFactory = null;
synchronized(this) {
if(this.sslContext != null) {
sslSocketFactory = this.sslContext.getSocketFactory();
}
}


if(sslSocketFactory == null) {
sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
}


return sslSocketFactory;
}


public synchronized void setSSLContext(SSLContext sslContext) {
this.sslContext = sslContext;
}

}

EasySSLProtocolSocketFactory 给我带来了问题,所以我最终实现了自己的 ProtocolSocketFactory。

首先你需要注册:

Protocol.registerProtocol("https", new Protocol("https", new TrustAllSSLSocketFactory(), 443));


HttpClient client = new HttpClient();
...

然后执行 ProtocolSocketFactory:

class TrustAllSSLSocketFactory implements ProtocolSocketFactory {


public static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(final X509Certificate[] certs, final String authType) {


}


public void checkServerTrusted(final X509Certificate[] certs, final String authType) {


}


public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};


private TrustManager[] getTrustManager() {
return TRUST_ALL_CERTS;
}


public Socket createSocket(final String host, final int port, final InetAddress clientHost,
final int clientPort) throws IOException {
return getSocketFactory().createSocket(host, port, clientHost, clientPort);
}


@Override
public Socket createSocket(final String host, final int port, final InetAddress localAddress,
final int localPort, final HttpConnectionParams params) throws IOException {
return createSocket(host, port);
}


public Socket createSocket(final String host, final int port) throws IOException {
return getSocketFactory().createSocket(host, port);
}


private SocketFactory getSocketFactory() throws UnknownHostException {
TrustManager[] trustAllCerts = getTrustManager();


try {
SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustAllCerts, new SecureRandom());


final SSLSocketFactory socketFactory = context.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
return socketFactory;
} catch (NoSuchAlgorithmException | KeyManagementException exception) {
throw new UnknownHostException(exception.getMessage());
}
}
}

注意: 这是使用 HttpClient 3.1和 Java 8实现的

对于 Apache HttpClient 4.5 + & Java8:

SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial((chain, authType) -> true).build();


SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, new String[]
{"SSLv2Hello", "SSLv3", "TLSv1","TLSv1.1", "TLSv1.2" }, null,
NoopHostnameVerifier.INSTANCE);
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();

但是如果您的 HttpClient 使用 ConnectionManager 来寻找连接,例如:

 PoolingHttpClientConnectionManager connectionManager = new
PoolingHttpClientConnectionManager();


CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();

HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory)没有效果,问题没有解决。

因为 HttpClient 使用指定的 ConnectionManager 来寻找连接,而指定的 ConnectionManager 没有注册我们自定义的 SSLConnectionSocketFactory。要解决这个问题,应该在 ConnectionManager 中注册自定义的 SSLConnectionSocketFactory。正确的代码应该是这样的:

PoolingHttpClientConnectionManager connectionManager = new
PoolingHttpClientConnectionManager(RegistryBuilder.
<ConnectionSocketFactory>create()
.register("http",PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory).build());


CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();

对于 HttpClient,我们可以这样做:

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);


String uri = new StringBuilder("url").toString();


HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
};


HttpClient client = HttpClientBuilder.create().setSSLContext(ctx)
.setSSLHostnameVerifier(hostnameVerifier).build()

按照下面给出的 Java 1.7指令,使用 InstallCert.Java 程序文件创建 SSL 证书。

Https://github.com/escline/installcert

你必须重新启动公猫

与 DefaultTrustManager 一起使用了以下内容,并且它在 httpclient 般的魅力中工作。非常感谢!@ Kevin 和其他捐款人

    SSLContext ctx = null;
SSLConnectionSocketFactory sslsf = null;
try {


ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);


sslsf = new SSLConnectionSocketFactory(
ctx,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());


} catch (Exception e) {
e.printStackTrace();
}


CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();

想把答案粘贴在这里:

在 ApacheHttpClient4.5.5中

如何使用 Apache 客户端4.5.5处理无效的 SSL 证书?

HttpClient httpClient = HttpClients
.custom()
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();

我碰巧遇到了同样的问题,突然之间我所有的进口货都不见了。我试图删除我的。M2文件夹。试图重新进口所有东西,但还是没用。 最后,我打开了一个网站,IDE 抱怨它无法在我的浏览器中下载。看到了它正在使用的证书,看到了我的

$ keytool -v -list  PATH_TO_JAVA_KEYSTORE

到我的密钥存储库的路径是/Library/Java/JavaVirtualMachines/jdk1.8.0 _ 171. jdk/content/Home/jre/lib/security/ccerts

那张证明不在那里。

所以您需要做的就是再次将证书放入 JAVA JVM 密钥存储库中。 可以使用下面的命令来完成。

$ keytool -import -alias ANY_NAME_YOU_WANT_TO_GIVE -file PATH_TO_YOUR_CERTIFICATE -keystore PATH_OF_JAVA_KEYSTORE

如果它询问密码,请尝试默认密码‘ changeit’ 如果在运行以上命令时出现权限错误。 在窗口中以管理模式打开它。 在 mac 和 unix 中使用 sudo。

成功添加密钥后, 你可以使用以下方法查看:

$ keytool -v -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

您可以使用 teh 命令查看 SHA-1

$ keytool -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts