How do I retrieve an untrusted SSL server certificate in order to review and trust it?(如何检索不受信任的 SSL 服务器证书以查看和信任它?)
问题描述
我的问题:
我想连接到可能使用 Java 默认不信任的证书的服务器(不限于 HTTPS 协议 -- 可以是 LDAP-over-SSL、可以是 SMTPS、可以是 IMAPS 等)(因为它们是自签名的).
I want to connect to servers (not limited to the HTTPS protocol -- could be LDAP-over-SSL, could be SMTPS, could be IMAPS, etc.) that may be using certificates that Java will not trust by default (because they are self-signed).
所需的工作流程是尝试连接,检索证书信息,将其呈现给用户,如果他接受,则将其添加到信任库,以便继续信任它.
The desired workflow is to attempt the connection, retrieve the certificate info, present that to the user and if he accepts it, add it to to the truststore so it'll be trusted going forward.
我在检索证书时遇到了困难.我有代码(见文章末尾),这些代码是我从这里和从回答有关 java SSL 的问题所指向的站点中抄来的.该代码简单地创建一个SSLSocket
,启动SSL 握手,然后向SSL 会话询问Certificate[]
.当我使用已经可信任的证书连接到服务器时,代码可以正常工作.但是当我使用自签名证书连接到服务器时,我得到了通常的结果:
I am stuck at retrieving the certificate. I have code (see at the end of the post) that I've cribbed from here and from sites pointed to by answers to questions about java SSL. The code simply creates an SSLSocket
, starts the SSL handshake, and asks the SSL session for the Certificate[]
. The code works fine when I'm connecting to a server using an already-trustable certificate. But when I connect to a server using a self-signed cert I get the usual:
Exception in thread "main" 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(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
[etc]
如果我使用 -Djavax.net.debug=all
运行,我会看到 JVM 确实检索了自签名证书,但会因为使用不受信任的证书而导致连接中断,然后才进入正题它将在哪里返回证书.
If I run with -Djavax.net.debug=all
I see that the JVM does retrieve the self-signed cert but will blow up the connection for using an untrusted cert before getting to the point where it'll return the certificates.
似乎是先有鸡还是先有蛋的问题.它不会让我看到证书,因为它们不受信任.但我需要查看证书才能将它们添加到信任库中,以便它们受到信任.你是如何摆脱这种局面的?
Seems like a chicken-and-egg problem. It will not let me see the certificates because they are not trusted. But I need to see the certificates to be able to add them to the truststore so they will be trusted. How do you break out of this?
例如,如果我将程序运行为:
For example, if I run the program as:
java SSLTest www.google.com 443
我得到一份 Google 正在使用的证书的打印输出.但是如果我运行它
I get a printout of the certs Google is using. But if I run it as
java SSLTest my.imap.server 993
我得到了上面提到的异常.
I get the exception referenced above.
代码:
import java.io.InputStream;
import java.io.OutputStream;
import java.security.cert.*;
import javax.net.SocketFactory;
import javax.net.ssl.*;
public class SSLTest
{
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: SSLTest host port");
return;
}
String host = args[0];
int port = Integer.parseInt(args[1]);
SocketFactory factory = SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
socket.startHandshake();
Certificate[] certs = socket.getSession().getPeerCertificates();
System.out.println("Certs retrieved: " + certs.length);
for (Certificate cert : certs) {
System.out.println("Certificate is: " + cert);
if(cert instanceof X509Certificate) {
try {
( (X509Certificate) cert).checkValidity();
System.out.println("Certificate is active for current date");
} catch(CertificateExpiredException cee) {
System.out.println("Certificate is expired");
}
}
}
}
}
推荐答案
看这个Andreas Sterbenz 的 InstallCert 实用程序的副本.
这篇关于如何检索不受信任的 SSL 服务器证书以查看和信任它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何检索不受信任的 SSL 服务器证书以查看和信任它?
基础教程推荐
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01