我正在尝试通过ssl与Java连接到我的一台服务器.我尝试了很多选项,这是我最好的尝试:
我 使用以下命令生成带有推荐脚本的jssecacerts:http://blogs.oracle.com/andreas/resource/InstallCert.java:java InstallCert ssl.someUrl.de changeit
在此之后我第二次做了命令:
Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...
No errors, certificate is already trusted
Server sent 1 certificate(s):
1 Subject EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
Issuer EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
sha1 f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
md5 f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d
Enter certificate to add to trusted keystore or 'q' to quit: [1]
Run Code Online (Sandbox Code Playgroud)
我将文件复制到默认目录,然后在Java trustStore中加载了证书
System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");
Run Code Online (Sandbox Code Playgroud)
然后我尝试连接
URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Run Code Online (Sandbox Code Playgroud)
我在第3行得到错误:(找不到匹配ssl.someUrl.de的名字)
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching ssl.someUrl.de found
Run Code Online (Sandbox Code Playgroud)
这是默认的plesk证书的原因还是其他错误?
设置:JRE 6.20,Netbeans 6.8,Windows7 64bit
Bru*_*uno 62
看起来您尝试连接的服务器的证书与其主机名不匹配.
当HTTPS客户端连接到服务器时,它会验证证书中的主机名是否与服务器的主机名匹配.证书不可靠,它必须匹配您想要与之交谈的服务器.(作为类比,即使您相信护照是合法的,您仍然必须检查它是否是您想要与之交谈的人,而不仅仅是您认为合法的护照.)
在HTTP中,这是通过检查:
证书包含与主机名匹配的DNS主题备用名称(这是标准扩展名);
如果失败,主题专有名称的最后一个CN(如果需要,这是主要名称)与主机名匹配.(参见RFC 2818.)
如果没有证书,很难说出主题替代名称是什么(尽管如果你连接浏览器并查看其内容的更多细节,你应该能够看到它.)主题专有名称似乎是:
EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US
Run Code Online (Sandbox Code Playgroud)
(因此,如果你没有DNS的主题替代名称,那么它需要是CN = ssl.someUrl.de而不是CN = plesk:ssl.someUrl.de已经存在;我的猜测是你没有.)
您可以使用HttpsURLConnection.setHostnameVerifier(..)绕过主机名验证.编写一个自定义的HostnameVerifier并不太难以通过验证验证,尽管我建议只在证书与此处有关的证书时才这样做.您应该能够使用SSLSession参数及其getPeerCertificates()方法获取它.
(此外,您不需要像完成它那样设置javax.net.ssl.*属性,因为您仍然使用默认值.)
或者,如果您可以控制要连接的服务器及其证书,则可以创建与上述命名规则相匹配的证书(CN应该足够,但主题替代名称是一种改进).如果自签名证书足以满足您的要求,请确保其公用名(CN)是您尝试与之通信的主机名(没有完整的URL,只有主机名).
jam*_*ing 29
在Java 8中,您可以使用以下代码跳过服务器名称检查:
HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);
Run Code Online (Sandbox Code Playgroud)
但是这应该仅用于开发!
Cas*_*rin 15
我创建了一个方法fixUntrustCertificate(),因此当我处理不在受信任CA中的域时,您可以在请求之前调用该方法.这段代码将在java1.4之后运行.此方法适用于所有主机:
public void fixUntrustCertificate() throws KeyManagementException, NoSuchAlgorithmException{
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// set the allTrusting verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
Run Code Online (Sandbox Code Playgroud)
小智 6
如果您正在寻找 Kafka 错误,这可能是因为 Kafka 的版本从 1.x 升级到 2.x。
javax.net.ssl.SSLHandshakeException: 一般 SSLEngine 问题 ... javax.net.ssl.SSLHandshakeException: 一般 SSLEngine 问题 ... java.security.cert.CertificateException: 找不到匹配的名称 ***
或者
[Producer clientId=producer-1] 连接到节点 -2 的身份验证失败,原因是:SSL 握手失败
ssl.endpoint.identification.algorithm 的默认值已更改为 https,它执行主机名验证(否则可能进行中间人攻击)。将 ssl.endpoint.identification.algorithm 设置为空字符串以恢复之前的行为。Apache Kafka 2.0.0 中的显着变化
解决方案:SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""
小智 5
我在这里找到了一个很好的解决方案:http : //www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/
但我的问题有点不同,解决方法也不同。
Web 服务位于远程主机上。例如:https : //some.remote.host/MyWebService?wsdl
但它只能通过 IP 用于任何客户端,但证书是为域创建的:some.remote.host (CN=some.remote.host)。并且此域无法通过 IP 解析,因为它未出现在 DNS 中)。
所以出现了同样的问题:如果我使用 IP 通过 ssl 连接到 Web 服务,则无法访问,因为证书 CN=some.remote.host 并且它不等于我指定的主机名(即主机 IP) .
我已经通过将此主机名与 /etc/hosts 文件中的 IP 匹配来解决它。问题已解决。
但是如果Web Service托管在localhost应用程序服务器上,它认为应该像mkyong在他的文章中描述的那样解决。
用例:我正在使用自签名证书进行开发localhost。
错误:由以下原因引起:java.security.cert.CertificateException:未localhost找到名称匹配
解决方案: 当您生成自签名证书时,请确保您回答如下问题:
What is your first and last name?
[Unknown]: localhost
//The rest you can fill accordingly
Run Code Online (Sandbox Code Playgroud)
1.生成自签名证书:
keytool -genkeypair -alias netty -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 4000
Enter keystore password: ***
Re-enter new password: ***
What is your first and last name?
[Unknown]: localhost
//The rest you can fill accordingly
Run Code Online (Sandbox Code Playgroud)
2.将证书复制到src/main/resources中(如果需要)
3. 更新证书
keytool -v -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore "%JAVA_HOME%\jre\lib\security\cacerts" -deststoretype jks
Run Code Online (Sandbox Code Playgroud)
4.更新您的配置(在我的例子中为application.properties):
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=jumping_monkey
server.ssl.key-store-type=pkcs12
server.ssl.key-alias=netty
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
122906 次 |
| 最近记录: |