Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中打开自签名HTTPS SSL URL的简单方法?_Java_Ssl - Fatal编程技术网

在java中打开自签名HTTPS SSL URL的简单方法?

在java中打开自签名HTTPS SSL URL的简单方法?,java,ssl,Java,Ssl,我正在构建一个需要在java中打开自签名HTTPS SSL URL的应用程序。我了解到,您可以通过添加对HttpsURLConnection.setDefaultHostnameVerifier()的调用来绕过SSL问题,您可以在该调用中指定允许哪些主机名 但是,我还有第二个问题,我的服务器正在运行自签名证书。因此,即使绕过主机名,我也会遇到如下异常: javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorExce

我正在构建一个需要在java中打开自签名HTTPS SSL URL的应用程序。我了解到,您可以通过添加对HttpsURLConnection.setDefaultHostnameVerifier()的调用来绕过SSL问题,您可以在该调用中指定允许哪些主机名

但是,我还有第二个问题,我的服务器正在运行自签名证书。因此,即使绕过主机名,我也会遇到如下异常:

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径

我环顾四周,找到的唯一解决方案是将证书添加到java密钥存储中,但这对我来说是个问题,因为我无法控制他们何时或如何更新java,而且我已经了解到密钥存储在更新之间不会被保留,并且我无法访问JVM之外的系统


我的应用程序只会对单个服务器进行调用,因此,如果有一种方法可以绕过自签名限制,并且从不查阅密钥库,那么这不会是一个安全问题,但是有没有一种方法可以做到这一点呢?

尽管我不想这么说,但有时候还是顺其自然为好

Java正试图通过使用正确的SSL验证实践使应用程序更加安全。在这种情况下,它是成功的:如果您能够告诉程序“没关系,接受不受信任的自签名证书”,您的程序将很容易受到中间人攻击,Mallory将其服务器放在中间(带有自己的自签名证书,与您的证书一样有效!)在它试图与之通信的主机和目标之间。然后,他继续阅读所有你认为是美好和安全的交通,你甚至没有注意到

因此,遗憾的是,您断言告诉Java“连接到此主机时信任任何自签名证书”是安全的,这是不正确的

您可以从中获得免费、完全有效的SSL证书。他们是好人

我正在构建一个需要打开自签名HTTPS SSL的应用程序 java中的URL。我了解到,您可以通过以下方式绕过SSL问题 添加对HttpsURLConnection.setDefaultHostnameVerifier()的调用,其中 你说什么主机名是允许的

您的问题中有一些误解:
主机名验证与证书是否自签名无关。
这是一种验证,它将您尝试访问的域与证书信息(CN或Subject Alt Name)匹配

如果需要接受与url不匹配的证书,则需要配置验证器(完全不推荐!!!)

关于自签名。
这无关紧要。
您可以将应用程序配置为加载自定义信任库,其中包含应用程序将信任的证书。事实上,这是最好的方法(比使用Java的cacerts更好)。
您所要做的就是将证书导入密钥库(JKS或PKCS12),并将其加载到应用程序中的自定义文件中。

就在google arround,有很多例子,例如,

这就是PKI的工作原理-您必须拥有完整的信任链,从存储在密钥库中的某个受信任证书到您的证书。所以你可以

  • 将您的证书设置为受信任
  • 请已受信任的人(即密钥库中有受信任证书的人)为您的证书签名
试图绕过这一点不是个好主意。您可以在一些Java安装后钩子中安装证书,您可以让一些cron作业定期检查证书,或者在异常处理中进行检查。您甚至可以通过这种方式从服务器下载证书,并在每次证书更改时安装它(使用openssl提取证书很容易)。但看在上帝的份上,如果你决定做这样的事情,至少写一些关于它的审计日志给第三台机器,以确保有人阅读它

你也可以在门上写上“黑客友好”:

(请注意,当您在问题中谈论“密钥库”时,实际上您是在谈论信任存储(这是一个密钥库)。关于这一令人困惑的Java术语的更多详细信息,请参阅r。)

我的应用程序将只对单个服务器进行调用,因此如果存在 一种绕过自签名限制的方法,并且从不咨询 密钥库,这不会是一个安全问题,但有办法做到这一点吗 这个

实际上,这将是一个安全问题。您的应用程序可能确实只打算调用一台服务器,但信任存储正好帮助确保您正在连接到要连接的机器。如果没有它,您将无法知道是连接到该服务器还是MITM服务器

如果希望SSL/TLS提供安全性,请不要绕过这些规则。(特别是,不要使用接受任何证书的信任管理器。)

我环顾四周,找到的唯一解决方案是添加 证书到java密钥存储,但这对我来说是个问题 因为我无法控制他们何时或如何更新java,而且我 了解到密钥库在更新之间没有保留,我没有 在JVM之外访问系统

引用我自己的话(针对更具体的问题):

正确的方法是使用
keytool
将此自签名证书导入客户端的信任存储,例如:

keytool -import -file server-cert.pem -alias myserver -keystore mytruststore.jks
您可以直接在JRE的信任存储(lib/security/cacerts)中执行此操作,这可能缺乏一些灵活性,也可以在您自己的此文件副本中执行此操作,然后将其设置为信任存储(默认密码是OSX上的
changeit
changeme
)。您可以使用为应用程序全局配置此信任库