Showing posts with label SunX509. Show all posts
Showing posts with label SunX509. Show all posts

Wednesday, 22 January 2014

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part4

Debug the Client/Server Communication 

This part depends on the:
  • Communication credentials, or the Keystore/Trustore file created in Part-1
  • Server implemented in Part-2
  • Client implemented in Part-3

To start with we need to include on our JVM arguments on both client and server the following option:
-Djavax.net.debug=all

So for example to run the server we do:
$ java TwoWaySslServer -Djavax.net.debug=all

As a result, we have all the debugging information we need for network operations from the JVM and the imported classes, like SSLServerSocket.

Having our server in debug mode, we can observe that the Keystore (mysystem.jks) was loaded correctly if we notice the following private key log entry:

***
found key for : mysystem
chain [0] = [
[
  Version: V3
  Subject: CN=mysystem, L=Chalandri, ST=Athens, C=GR
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 1024 bits
  modulus: 127165120252867655295291767293201905001859144644390543231567027664179957281793248832544049047501722299712701237862474932181664724853946779349563166371011412260964043029373627517538842247060193170649833260910804612805979354599504164270912367917881965338674535760796311997608873587262396297225200721624071184029
  public exponent: 65537
  Validity: [From: Wed Jan 22 12:46:44 CET 2014,
               To: Mon Jan 22 12:46:44 CET 2024]
  Issuer: CN=mysystem, L=Chalandri, ST=Athens, C=GR
  SerialNumber: [    af1b0164 bd3095fa]

Certificate Extensions: 3
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 03 B2 09 B4 89 36 32 E4   D6 A3 51 4A 5D 3B CD ED  .....62...QJ];..
0010: B2 00 77 EC                                        ..w.
]

]

[2]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

[3]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 03 B2 09 B4 89 36 32 E4   D6 A3 51 4A 5D 3B CD ED  .....62...QJ];..
0010: B2 00 77 EC                                        ..w.
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 78 58 C9 F5 C0 42 2D 62   B5 0D 8A 79 6B 57 5A 85  xX...B-b...ykWZ.
0010: 8C 85 20 4D 7B B3 8A 0A   DF 83 D9 D1 5A FA F6 26  .. M........Z..&
0020: 53 56 DB FE B3 82 42 35   0C BF E8 BD 75 0A 18 7A  SV....B5....u..z
0030: D7 B0 36 E5 4E F9 82 FB   23 57 EC 23 3F D0 92 9E  ..6.N...#W.#?...
0040: 9C D6 FA 26 32 7C B6 4A   62 A4 4B AB F7 D3 64 7C  ...&2..Jb.K...d.
0050: 37 92 ED F2 2B 62 BC E7   A6 35 E6 87 67 9E BD 0D  7...+b...5..g...
0060: 97 5E 0F 31 A9 B1 AB 64   CC F9 4B 51 3E 90 7B 2F  .^.1...d..KQ>../
0070: E9 2E 23 E5 BC D3 DA 32   20 3B 6C 2C B8 E2 7C 6B  ..#....2 ;l,...k

]

If we don´t find our private key in the above debugging information, we need to check again the parameters:

  System.setProperty("javax.net.ssl.keyStore","mysystem.jks");
  System.setProperty("javax.net.ssl.keyStorePassword","welcome");

Similarly again in debugging mode, we can observe that the Trustore (mysystem.jks) was loaded correctly from server if we notice the following log entry:
***
trustStore is: mysystem.jks
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=mysystem, L=Chalandri, ST=Athens, C=GR
  Issuer:  CN=mysystem, L=Chalandri, ST=Athens, C=GR
  Algorithm: RSA; Serial number: 0xaf1b0164bd3095fa
  Valid from Wed Jan 22 12:46:44 CET 2014 until Mon Jan 22 12:46:44 CET 2024

trigger seeding of SecureRandom
done seeding SecureRandom
SERVER
 socket class: class com.sun.net.ssl.internal.ssl.SSLServerSocketImpl
 Socker address = 0.0.0.0/0.0.0.0
 Socker port = 8095
 Need client authentication = true
 Want client authentication = false
 Use client mode = false

If we don´t find the self signed certificate key in the above debugging information, we need to check again the parameters:

System.setProperty("javax.net.ssl.trustStore","mysystem.jks");
System.setProperty("javax.net.ssl.trustStorePassword","welcome");

Some really interesting Exceptions you may come across while debugging your application:

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
Caught on Server
Probably you have created the client socket with something like:
clientSocket = new Socket();
Instead of :
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
clientSocket = (SSLSocket) factory.createSocket("localhost",port);


java.lang.IllegalStateException: KeyManagerFactoryImpl is not initialized
You have not initialized KeyManagerFactory object, meaning that you should call method init() with a valid KeyStore and Certificate Password:
  String keystoreFile = "/opt/mysystem/etc/mysystem.jks";
  String keystorePassword = "welcome";
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(new FileInputStream(keystoreFile), keystorePassword );
  KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
  kmf.init(ks,"myCertificatePassword");

java.security.cert.CertificateException: No X509TrustManager implementation avaiable
Check the trustrore. Ensure that property javax.net.ssl.trustStore is set appropriately.

javax.net.ssl.SSLHandshakeException: null cert chain
Received on server
Check that both Client and server share the trustore.
Check that trustore contains the same signed certificate

java.io.IOException: Keystore was tampered with, or password was incorrect
Check the Keystore password, system property javax.net.ssl.keyStorePassword

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part3

Step 3: The Client (Get the complete code here)

The client also requires the Keystore/Trustore created in Part-1

Again in the client we have to do a couple of things similar to the server:

The first is to specify the Java Keystore/Trustore we created in  Part-1 of this article:

System.setProperty("javax.net.ssl.keyStore","mysystem.jks");
System.setProperty("javax.net.ssl.keyStorePassword","welcome");

System.setProperty("javax.net.ssl.trustStore","mysystem.jks");
System.setProperty("javax.net.ssl.trustStorePassword","welcome");

Similarly with the server side described in Part-2, we have to create the client socket as an SSLSocket:

SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();    
SSLSocket sslSock = (SSLSocket) factory.createSocket("localhost",8095);

The entire code of the client can be downloaded here.

Next article, Part-4, of this Blog series will assist you to debug the SSL/TLS client/server communication.

Implementing 2-way SSL in Java using TLS and Self Signed Certificates part2

Step 2: The server (Get the complete server code here)

Requires the Trustore/Keystore created in Step-1.

To write the server process in Java is pretty simple. You just have to do a couple of steps:
Specify a couple of properties so that the Trustore/Keystore can be loaded like the following code fragment shows:

System.setProperty("javax.net.ssl.keyStore","mysystem.jks");
System.setProperty("javax.net.ssl.keyStorePassword","welcome");

System.setProperty("javax.net.ssl.trustStore","mysystem.jks");
System.setProperty("javax.net.ssl.trustStorePassword","welcome");

Create the ServerSocket as anSSLServerSocketlike the following code fragment shows:
 
char ksPass[] = "welcome".toCharArray();
char ctPass[] = "welcome".toCharArray();

//Create and load the Keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("ianalyzer.jks"), ksPass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctPass);

//Create the ServerSocket as an SSLServerSocket
SSLContext secureSocket = SSLContext.getInstance("TLS");
secureSocket.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = secureSocket.getServerSocketFactory();
ssocket = (SSLServerSocket) ssf.createServerSocket(8095);
SSLServerSocket ss = (SSLServerSocket) ssocket;

//This explicitly states TLS with 2-way authentication
ss.setNeedClientAuth(true); 

The entire code for server implementation can be downloaded here.