我正在添加到我们的大型Java应用程序的模块必须与另一家公司的SSL安全网站进行交谈.问题是该站点使用自签名证书.我有一份证书副本,以验证我没有遇到中间人攻击,我需要将此证书合并到我们的代码中,以便与服务器的连接成功.
这是基本代码:
void sendRequest(String dataPacket) {
String urlStr = "https://host.example.com/";
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setMethod("POST");
conn.setRequestProperty("Content-Length", data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
o.write(data);
o.flush();
}
Run Code Online (Sandbox Code Playgroud)
在没有为自签名证书进行任何额外处理的情况下,这会在conn.getOutputStream()处死,但有以下异常:
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
....
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
....
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path …
Run Code Online (Sandbox Code Playgroud) 有没有人遇到他们必须处理.truststore文件的地方?并知道如何将.cer导入.truststore文件?
我不确定是否必须使用Java Keytool或Linux命令(例如openssl命令).
谢谢
我正在用Java编写一个应用程序,它通过HTTPS连接到两个Web服务器.一个通过默认的信任链获得证书,另一个使用自签名证书.当然,连接到第一台服务器是开箱即用的,而在我使用该服务器的证书创建一个trustStore之前,使用自签名证书连接到服务器不起作用.但是,与默认可信服务器的连接不再起作用,因为显然我创建自己的默认trustStore会被忽略.
我找到的一个解决方案是将证书从默认的trustStore添加到我自己的.但是,我不喜欢这个解决方案,因为它需要我继续管理那个trustStore.(我不能假设这些证书在可预见的未来仍然是静态的,对吧?)
除此之外,我发现了两个有着类似问题的5岁线程:
他们都深入到Java SSL基础架构.我希望到现在有一个更方便的解决方案,我可以在我的代码的安全审查中轻松解释.
我已经设置了一个自签名证书来测试ssl java连接 - 但是,它拒绝找到java trustStore.我已经在/ Java/jre6/lib/security中保存了它的副本,除了编译类的文件夹(使用netbeans)以及/ java/jre6/bin之外,上述任何一个都不起作用,因为当我运行以下 - trustStore = null.
public class ShowTrustStore {
public static void main(String[] args) {
System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
System.setProperty("javax.net.ssl.trustStrore", "cacerts.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
String trustStore = System.getProperty("javax.net.ssl.trustStore");
if (trustStore == null) {
System.out.println("javax.net.ssl.trustStore is not defined");
} else {
System.out.println("javax.net.ssl.trustStore = " + trustStore);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何正确设置路径?
**********UPDATE************使用getFile()方法和一些其他调试数据:
package ssltest;
public class Main {
public static void main(String[] args) {
// System.setProperty("javax.net.ssl.keyStore", "/keystore.jks");
// System.setProperty("javax.net.ssl.trustStrore", "/java.home/cacerts.jks");
// System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
// System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
try {
Main.class.getResource("trustStore.jks").getFile(); …
Run Code Online (Sandbox Code Playgroud) 我使用的是springBootVersion 1.2.0.RELEASE.我正在尝试通过配置我的密钥库和信任库application.properties
.
当我添加以下设置时,我可以让密钥库工作,但不能使用信任库.
server.ssl.key-store=classpath:foo.jks
server.ssl.key-store-password=password
server.ssl.key-password=password
server.ssl.trust-store=classpath:foo.jks
server.ssl.trust-store-password=password
Run Code Online (Sandbox Code Playgroud)
但是,如果我通过gradle添加信任库:
bootRun {
jvmArgs = [ "-Djavax.net.ssl.trustStore=c://foo.jks", "-Djavax.net.ssl.trustStorePassword=password"]
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好.
有没有人用过application.properties
信托商店?
我对文件cacerts
和jssecacerts
文件之间的区别感到非常困惑.
我知道默认情况下java会查找该jssecacerts
文件,然后查找该cacerts
文件.
但jssecacerts
文件的重点是什么?
我的理解是,如果需要使用新的信任库,则cacerts
应该制作一份副本,并将所有新的可信CA添加到该副本中.cacerts
然后,-Djavax.net.ssl.trustStore
系统属性应引用(使用新CA)的副本.这样,在该计算机上运行的其他Java应用程序将不会意外地信任非默认CA.
我不太了解密钥库/信任库术语,但就我而言,信任库保持对等服务器信任的证书.
我可以使用查看密钥库的内容
keytool -list -keystore refArchive/testkeystore
Enter keystore password: password
Run Code Online (Sandbox Code Playgroud)
信任库有没有相应的东西?如何查看受信任的证书?
谢谢!
我需要在公司内部网上使用curtom根证书,并在Mac OS中加载它们TrustStore(KeyChain)确实解决了所有浏览器和GUI应用程序的问题.
它似乎适用curl
于Mac OS X附带的版本,但它不适用于python,即使Mac OS 10.12 Sierra附带的版本(Python 2.7.10)
不过,似乎我会受到以下打击:
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>
Run Code Online (Sandbox Code Playgroud)
因为我在很多Python工具中遇到这个问题,如果我找到一种方法来避免它而不必修补它,我将非常感激.
自己提供自定义CA证书不是一种选择,因为我无法修补我使用的数十种Python工具.
大多数工具都使用该requests
库,但有一些工具直接在Python中使用本机ssl支持.
我刚刚创建了一个带有java keytool的信任库(用于没有CA证书的服务器的服务器身份验证).但是我只是注意到一些奇怪的事 我这样开始我的客户:
java -Djavax.net.ssl.trustStore=<PATHSTUFF>/client.keystore -classpath <STUFF> Client
Run Code Online (Sandbox Code Playgroud)
(注意:没有指定密码)
以上呼叫有效.
但是,当我尝试这个:
java -classpath <STUFF> Client
Run Code Online (Sandbox Code Playgroud)
这是行不通的.(显然它不起作用,它需要信任库).
我本以期需要传递这个选项(但我没有):
-Djavax.net.ssl.trustStorePassword=mypass
Run Code Online (Sandbox Code Playgroud)
问题:您是否需要密码才能访问信任库?密码只是用于修改吗?密钥库怎么样?
truststore ×10
java ×6
keystore ×6
ssl ×6
jsse ×3
certificate ×1
keytool ×1
macos ×1
properties ×1
python ×1
spring-boot ×1