SSL Certificate Verification : javax.net.ssl.SSLHandshakeException

后端 未结 3 1948
别那么骄傲
别那么骄傲 2020-12-29 00:13

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         


        
3条回答
  •  星月不相逢
    2020-12-29 00:43

    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.

    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
    

    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
    

    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
    

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

    openssl s_client -connect : -CAfile 
    

    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
    

    Is it OK to skip SSL verification ?

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

    This comes to mind: The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software.


    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return 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 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.

    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.

    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.

    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.

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

提交回复
热议问题