Tag Archives: Java

Disabling SSL Certificate Validation

Recently i came across two SSL-related exceptions when writing a testing Spring-based client application using RestTemplate. Because both of them are related to an untrusted connection when making HTTPS calls (as a result of self-signed SSL certificate configured in Tomcat), and both have one common solution, i thought i’ll share it with You.

 

Exceptions thrown:

  • java.security.cert.CertificateException: No name matching my.company.com found; nested exception is 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

Solution:

  • disabling SSL certificate validation (unless you want to go the “hard way” of installing a correct/SSL Authority-signed certificate)
  • This is how i did it in Java:

 

import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class SSLCertificateValidation {

    public static void disable() {
        try {
            SSLContext sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = { new NullX509TrustManager() };
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private static class NullX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    private static class NullHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

}

The complete example is available as a Gist.

 

What you now have to do, is to invoke SSLCertificateValidation.disable() prior to making a HTTPS call using RestClient. Simple as that.

Producing JWT tokens

To produce the JWT token i’ll be using the Nimbus JOSE+JWT Java library, which implements the Javascript Object Signing and Encryption (JOSE) suite of specifications as well as the closely related JSON Web Token (JWT) specification.

Technologies used:

  • Apache Maven 3.0.5
  • Nimbus JOSE+JWT 2.16
  • Java 7

 

First, let’s add maven dependency for Nimbus JOSE+JWT lib:

<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>2.16</version>
</dependency>

 

…and start composing the JWT reserved claims right away:

JWTClaimsSet jwtClaims = new JWTClaimsSet();
jwtClaims.setIssuer("https://my-auth-server.com");
jwtClaims.setSubject("Mariusz");
List aud = new ArrayList<>();
aud.add("https://my-web-app.com");
aud.add("https://your-web-app.com");
jwtClaims.setAudience(aud);
jwtClaims.setExpirationTime(new Date(new Date().getTime() + 1000*60*10));
jwtClaims.setNotBeforeTime(new Date());
jwtClaims.setIssueTime(new Date());
jwtClaims.setJWTID(UUID.randomUUID().toString());

as you can see, we’re setting up all of the Reserved Claim Names mentioned in my earlier post on JWT (ie. Issuer, Subject, Audience, Expiration Time (to 10 minutes), Not Before Time, Issued At Time and the JWT ID) and using random UUID as the identifier of the token.

 

When printed out the above, you should see something similar to this:

{
    "exp":1373625160,
    "sub":"Mariusz";,
    "nbf":1373624561,
    "aud":[
        "https:\/\/my-web-app.com",
        "https:\/\/your-web-app.com"
    ],
    "iss":"https:\/\/my-auth-server.com";,
    "jti":"c79772ea-8777-44dc-a0fe-9001aeee9d02",
    "iat":1373624561
}

 

now, let’s create the JWT header and specify RSA-OAEP as the encryption algorithm and 128-bit AES/GCM as the encryption method that will be used to protect the JWT token:

JWEHeader header = new JWEHeader(
    JWEAlgorithm.RSA_OAEP,
    EncryptionMethod.A128GCM
);

 

next create the EncryptedJWT object that will be later used to perform the RSA encryption:

EncryptedJWT jwt = new EncryptedJWT(header, jwtClaims);

 

…create an RSA encrypter with the specified public RSA key:

RSAEncrypter encrypter = new RSAEncrypter(publicRsaKey);

(for details on how to generate RSA keys, please read my post on “RSA Keys Generation”)

 

and do the actual encryption:

jwt.encrypt(encrypter);

 

finally, we can serialize to JWT compact form in order to print it out to the screen nicely:

String jwtString = jwt.serialize();

 

what you should see after performing the steps above, is something similar to this:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.ZyVpnDsmei
R_krnjTvMkB7a-DJrgdvwzXsMImIUS6x7B3yLEH5igpfiGfMD79SqYW5P
Fd7PrXVvNhq4Gs0YSg8qPPlPCjmaW7OnR9Oi891PRL1PyF0HqGzJJacZI
uu_jbeY0MQ9Z3hzNcuivhak60YFWLlGQWA7l4e7tkX4Hs4.fKF7TxNXc_
TmDl_P.AEPF230Ib8AeioJ6A4Kg0YXbYjaO4O4LVBu6qHQN1BP7ri_jc5
uCcIe02oFNEXoJZnSlaZP84LOZcnloNX6JBrLQnDr90jxkeDcoyiiLoxC
nebYJIksqyvxsGOvsAMS7MUt1Ms3Ua7tBv5pft0YVvIY9CK0oPdEyCAiu
vBp6KOR4Y9xkTy1xev5SUcWQjmskUlqtLnsO7mXpsMI09xTq13FgM2fTS
C5MIXFx2un8n8esh_rFMIfTlqLky1oa7dvb28ICjbYZPEq4CpCOeeMcQC
KliSy6A.zUGNd9GHWAY0m_m7xrQOOg

 

Now, if you’d like to read the data back from the token using your private RSA key, you’d have to do the following:

parse the above JWT string using EncryptedJWT object:

EncryptedJWT jwt = EncryptedJWT.parse(jwtString);

 

create a decrypter with the specified private RSA key:

RSADecrypter decrypter = new RSADecrypter(privateRsaKey);

 

do the decryption:

jwt.decrypt(decrypter);

 

and print out the claims:

System.out.println("iss: " + jwt.getJWTClaimsSet().getIssuer());
System.out.println("sub: " + jwt.getJWTClaimsSet().getSubject());
System.out.println("aud: " + jwt.getJWTClaimsSet().getAudience().size());
System.out.println("exp: " + jwt.getJWTClaimsSet().getExpirationTime());
System.out.println("nbf: " + jwt.getJWTClaimsSet().getNotBeforeTime());
System.out.println("iat: " + jwt.getJWTClaimsSet().getIssueTime());
System.out.println("jti: " + jwt.getJWTClaimsSet().getJWTID());

 

resulting with the following output:

iss: https://my-auth-server.com
sub: Mariusz
aud: 2
exp: Fri Jul 12 12:32:40 CEST 2013
nbf: Fri Jul 12 12:22:41 CEST 2013
iat: Fri Jul 12 12:22:41 CEST 2013
jti: c79772ea-8777-44dc-a0fe-9001aeee9d02

 

 

If you’re interested in a complete source code of this example, please clone the following Gist available on my GitHub account.

 

 

 

Sources: