SSL证书验证:javax.net.ssl.SSLHandshakeException [英] SSL Certificate Verification : javax.net.ssl.SSLHandshakeException

查看:1174
本文介绍了SSL证书验证:javax.net.ssl.SSLHandshakeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过 Jersey客户端调用HTTPS REST API。在开发过程中,我偶然发现以下错误:

I am trying to call a HTTPS REST API through Jersey Client. And on the course of development i stumble upon following error :

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching mvn.signify.abc.com found
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:149)
    at com.sun.jersey.api.client.Client.handle(Client.java:648)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:670)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:503)
    at com.lftechnology.sbworkbench.utility.utils.PingFederateUtility.main(PingFederateUtility.java:32)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching mvn.signify.abc.com found

所以我把它搞砸了一下,找到了大量的解决方案,实际上有效。

So I goggled it out for a bit and found tons of solution for it , which actually works.


  1. 使用Jersey客户端的HTTPS

  2. https://gist.github.com/outbounder/1069465

  3. 如何修复java.security.cert.CertificateException:没有主题替代名称存在错误?

  4. http://www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/

  5. http://java.globinch.com/enterprise-java/security/fix-java-security-certificate-exception-no-matching-localhost-found/

  1. HTTPS using Jersey Client
  2. https://gist.github.com/outbounder/1069465
  3. How to fix the "java.security.cert.CertificateException: No subject alternative names present" error?
  4. http://www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/
  5. http://java.globinch.com/enterprise-java/security/fix-java-security-certificate-exception-no-matching-localhost-found/

他们在不同的领域,但他们有一个共同的解决方案来解决它。

They are in different domain but they have a common solution to work it out.

我目前在开发环境中使用自创的自签名证书。因此它必然会出现问题。

I am currently using a self created self-signed certificate in development environment. And hence it is bound to show up the issue.

上述解决方案侧重于跳过/允许验证所有证书。

The above mentioned solution focus on skipping / allowing all certificates to be verified.

但当我将其移至生产环境时,我可以从可信赖的来源访问有效签名证书。

But when i move it to the production environment , then i have access to Valid Signed Certificate from trustworthy source.


  1. 当我转向生产时,这些解决方案是否有任何帮助?

  2. 跳过SSL验证是否可以?


  3. 开发和生产环境实现通用解决方案的另一种替代方法是什么?

PS

我使用的解决方案是,

try
{
    // Create a trust manager that does not validate certificate chains
    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) {
        }
    }
    };

    // Install the all-trusting trust manager
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (KeyManagementException e) {
    e.printStackTrace();
}

然后我与泽西合作让它工作。它工作得很好。

which i then in-cooperate with Jersey to make it work. And it is working great.

所以,再次问题此解决方案是否适用于生产环境?

推荐答案


我目前在
开发环境中使用自创的自签名证书。 ... javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:找不到与
dev.ppc.lftechnology.com匹配的名称

I am currently using a self created self-signed certificate in development environment. ... javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching dev.ppc.lftechnology.com found

看来自签名证书不正确。

It appears the self signed certificate is incorrect.

以下是OpenSSL CONF file我用来创建自签名证书和证书请求,以便在测试期间使用。将其另存为 example-com.conf 。更改 [alternate_names] 下的DNS名称以满足您的口味。你甚至可以把 localhost localhost.localdomain 127.0.0.1 在那里进行测试。

Below is the OpenSSL CONF file I use to create self signed certificates and certificate requests to use during testing. Save it as example-com.conf. Change the DNS names under [ alternate_names ] to suit your tastes. You can even put localhost, localhost.localdomain and 127.0.0.1 in there for testing.

如果要创建自签名证书,请使用:

If you want to create a self signed certificate, then use:

openssl req -config example-com.conf -new -x509 -newkey rsa:2048 \
    -nodes -keyout example-com.key.pem -days 365 -out example-com.cert.pem

如果要创建将签名的签名请求(CSR)由受信任的机构,然后使用:

If you want to create a signing request (CSR) that will be signed by a trusted authority, then use:

openssl req -config example-com.conf -new -newkey rsa:2048 \
    -nodes -keyout example-com.key.pem -days 365 -out example-com.req.pem

自签名证书和签名请求之间的区别是 -x509 选项。当 -x509 存在时,将创建一个自签名证书。缺少 -x509 表示已创建请求。

The difference between a self signed certificate and a signing request is the -x509 option. With -x509 present, a self signed certificate is created. The absence of -x509 means a request is created.

如果要打印自签名证书或请求要查看其实际内容,请使用:

If you want to print your self signed certificate or request to see what's actually in it, then use:

openssl x509 -in example-com.cert.pem -text -noout
openssl req -in example-com.req.pem -text -noout

如果你想要测试服务器,然后使用 s_client

If you want to test the server, then use s_client:

openssl s_client -connect <server>:<port> -CAfile <trust-anchor.pem>

上述命令应该以类似的消息结束验证OK(0) 。如果您没有收到验证确定(0),请修复您的测试装备。一旦OpenSSL成功完成,那就成了你的基线。

The above command should finish with a message similar to Verify OK (0). If you don't receive Verify OK (0), then fix your test rig. Once OpenSSL completes successfully, then that becomes your baseline.

[ req ]
default_bits        = 2048
default_keyfile     = server-key.pem
distinguished_name  = subject
req_extensions      = req_extensions
x509_extensions     = cert_extensions
string_mask         = utf8only

[ subject ]
countryName         = Country Name (2 letter code)
countryName_default     = US

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = NY

localityName            = Locality Name (eg, city)
localityName_default        = New York

organizationName         = Organization Name (eg, company)
organizationName_default    = Example, LLC

# Use a friendly name here. Its presented to the user.
#   The server's DNS name show up in Subject Alternate Names. Plus, 
#   DNS names here is deprecated by both IETF and CA/Browser Forums.
commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default      = Example Company

emailAddress            = Email Address
emailAddress_default        = test@example.com

[ cert_extensions ]

subjectKeyIdentifier        = hash
authorityKeyIdentifier  = keyid,issuer

basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
# extendedKeyUsage  = serverAuth
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

[ req_extensions ]

subjectKeyIdentifier        = hash

basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
# extendedKeyUsage  = serverAuth
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

[ alternate_names ]

DNS.1       = example.com
DNS.2       = www.example.com
DNS.3       = mail.example.com
DNS.4       = ftp.example.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1








跳过SSL验证是否可以?

Is it OK to skip SSL verification ?

没有。这是非常不负责任的。如果你不打算正确使用PKIX,那么为什么要使用它呢?

No. That's very irresponsible. If you are not going to use PKIX correctly, then why use it at all?

这是我想到的:世界上最危险的代码:在非浏览器软件中验证SSL证书

HostnameVerifier allHostsValid = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

最好在密钥库中加载自签名证书(或加载私有CA),然后将其传递给 SSLContext.init 。然后一切都按预期工作,并且不需要信任所有内容或从验证返回 true

Its better to load your self signed certificate in a Keystore (or load your private CA), and then pass it to SSLContext.init. Then everything works as intended, and there's no need to trust everything or return true from verify.

Bruno和EJP有很多答案涵盖该主题。

Bruno and EJP have plenty of answers covering that subject.


为开发和生产环境实现通用解决方案的另一种替代方法是什么?

What are the other alternate way to achieve a common solution for both development and production environment?

使用格式良好的证书链回到受信任的根。

Use a well formed certificate that chains back to a trusted root.

为了进行测试,您可以创建自签名证书。或者,创建证书请求并由内部CA在私有PKI中签名。在这种情况下,您需要信任自签名证书或信任您的内部CA.

For testing, you can create a self signed certificate. Or, create a certificate request and have it signed by your internal CA in a private PKI. In this case, you need to trust your self signed certificate or trust your internal CA.

对于生产,您可以使用由CA的其中一个成员签名的证书动物园,所以组织外的其他人也信任它。 StartCom CACert 提供免费的Class 1证书。

For production, you can use a certificate signed by one of the members of the CA Zoo so others outside the organization trusts it too. StartCom and CACert offer free Class 1 certificates.

第1类证书通常经过域验证,不允许使用通配符。虽然Class 1是免费发行的,但他们会收取撤销费用,因为这是成本所在。

Class 1 certificates are usually domain validated and don't allow wild cards. While the Class 1 is issued for free, they charge for revocation because that's where the cost lies.

如果您需要外卡,那么您通常会购买一个类2或更高。

If you need a wild card, then you will usually to purchase a Class 2 or higher.

这篇关于SSL证书验证:javax.net.ssl.SSLHandshakeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆