Two Way SSL
Please note that the link and screenshot used in this post may be outdated as it was implemented few years back. Please use this for reference purpose only.
In Two Way SSL (mutual authentication) the client verifies the identity of the server, and then the server verifies the credentials of the client. The figure below gives an overview of the Two Way SSL process.
Two Way SSL Flow Diagram
Implementation
Weblogic Version: 10, Glassfish Version 3, OS: Windows
Example below shows how to configure Two Way SSL for client connecting to Weblogic/Glassfish Server. Both servers provide default keystore (database of private keys and certificate) which are complete in themselves for SSL implementation in testing environment. In production environment you should implement your own certificate signed by your own CA.
More information on configuring SSL on Weblogic at: Weblogic SSL
Java provides keytool, a key and certificate management utility. It enables users to administer their own public/private key pairs and associated certificates for use in self-authentication.
keytool stores the keys and certificates in a so-called keystore.
For more information on keytool visit: Keytool Tutorial
Following are the steps to implement Two Way SSL:
- Set the path to use keytool: set the path to your jdk
set path="c:\Program Files\Java\jdk{version}\bin"
-
Configure the servers to enable Two Way SSL
Weblogic
-
Configure the servers to enable Two Way SSL
For Weblogic
Start Weblogic -> Login to console -> Click on Environment -> Servers -> SSL ->Advanced
-
Make sure in Two Way Client Cert behavior option Client Certs Requested and Enforced is selected
Two Way SSL configuration on weblogic
Glassfish
Make sure that client authentication is enabled
Two Way SSL config for glassfish
-
-
To view the information about certificate(s) in default keystore
Weblogic
C:\>keytool -list -v -keystore D:\Oracle\Middleware\wlserver_10.3\server\lib\DemoIdentity.jks
Default Password for DemoIdentity.jks is DemoIdentityKeyStorePassPhrase
Glassfish
C:\>keytool -list -v -keystore "c:\Program Files\glassfish-v3- prelude\glassfish\domains\domain1\config\keystore.jks
Keystore password is masterpassword of domain that is defined by user during domain creation. (For netbeans glassfish the password is “changeit”)
-
Export the certificate in keystore to a file. This certificate file will be imported to client keystore.
Weblogic
C:\>keytool -export -alias demoidentity -file D:\certificates\server.cer –keystore D:\Oracle\Middleware\wlserver_10.3\server\lib\DemoIdentity.jks
Glassfish
C:\> keytool -export -v -alias s1as -file D:\certificates\glasscert.cer –keystore "D:\Program Files\glassfish-v3-prelude-b28c\glassfish\domains\domain1\config\keystore.jks"
-
To print the information about the certificate created
C:\>keytool -printcert -v -file D:\certificates\server.cer
-
To view the information about certificates in the client keystore(Java provides its own truststore which is placed in
C:\Program Files\Java\jdk1.6.0_06\jre\lib\security
directory with name cacertsC:\>keytool -list -v -keystore "C:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts"
-
Import the server certificate into the client cacert
Weblogic
C:\>keytool -import -alias demoidentity -trustcacerts -file D:\certificates\server.cer - keystore "c:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts"
Glassfish
C:\>keytool -import -v -trustcacerts -alias s1as -keystore "C:\Program Files\Jav a\jdk1.6.0_06\jre\lib\security\cacerts" -file D:\certificates\glasscert.cer
-
Import the client certificate into the server cacert
Weblogic
C:\>keytool -import -v -trustcacerts -alias clientalias -keystore D:\Oracle\Middleware\wlserver_10.3\server\lib\DemoTrust.jks -file D:\certificates\clientcert.cer
Glassfish
keytool -import -v -trustcacerts -alias clientalias -file D:\certificates\clientcert.cer -keystore "D:\Program Files\glassfish-v3-prelude-b28c\glassfish\domains\domain1\config\cacerts.jks"
Additional Information
Note: If you are using self-signed certificate include following property in JAVA_OPTIONS of setDomainEnv of weblogic else weblogic will show Basic CA constraint error and restart the server.
-Dweblogic.security.SSL.enforceConstraints=off
set JAVA_OPTIONS=%JAVA_OPTIONS% %JAVA_PROPERTIES% -Dweblogic.security.SSL.enforceConstraints=off
Errors and Solution
Error
If you get the following error while running your client:
javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhos t:7002/BasicOperations/BasicOperationService?wsdl. It failed with:
Received fatal alert: handshake_failure.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unkn own Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.(Unknown Source)
at basicoperationservice.wsdl.BasicOperationService.(BasicOperatio nService.java:46)
at client.ClientMain.subtraction(ClientMain.java:51)
at client.ClientMain.main(ClientMain.java:91)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_ failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
Solution
Make sure that certificates are imported correctly on both client and server side. Error signifies that either server hello or client hello was incomplete.
To check for detailed debug information for SSL include the following property during invocation of client
-Djavax.net.debug=ssl or –Djavax.net.debug=handshake java -Djavax.net.debug=ssl
or
You can include it in your code also System.setProperty(“javax.net.debug”,”ssl”);
Error
javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhos t:7002/BasicOperations/BasicOperationService?wsdl. It failed with:
sun.security.validator.ValidatorException: PKIX path building failed: su n.security.provider.certpath.SunCertPathBuilderException: unable to find valid c ertification path to requested target.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unkn own Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.(Unknown Source)
at basicoperationservice.wsdl.BasicOperationService.(BasicOperatio nService.java:46)
at client.ClientMain.subtraction(ClientMain.java:51)
at client.ClientMain.main(ClientMain.java:91)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.Validator Exception: PKIX path building failed: sun.security.provider.certpath.SunCertPath BuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
Solution
Error signifies that the client was not able to find a valid certificate keystore path. Include the following properties during client invocation
-Djavax.net.ssl.keyStore="C:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts" - Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.trustStore="C:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts" - Djavax.net.ssl.trustStorePassword=changeit
For example:
java -Djavax.net.ssl.keyStore="C:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts" -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.trustStore="C:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts" - Djavax.net.ssl.trustStorePassword=changeit
Error
When Weblogic is acting as client (i.e. when service deployed on weblogic is accessing the service deployed on another server) in Two Way SSL, you may get the following error “No suitable identity certificate chain has been found.”
Solution
Go to SSL tab of your server where application is deployed and enable Use Server Certs
Error
If you get the following error while running your client:
javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhos t:7002/BasicOperations/BasicOperationService?wsdl. It failed with:
java.security.cert.CertificateException: No subject alternative names present.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:136) at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:122)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:226)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:189)
at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:159)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:81)
Solution
Include the following code in your codebase
static {
//WORKAROUND. TO BE REMOVED. javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new
javax.net.ssl.HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return true;
}
});
}
Or For Weblogic goto
Start Weblogic -> Login to console -> Click on Environment -> Servers -> SSL -> Advanced -> Set the Hostname Verification to None
SSL Hostname Verification Weblogic Setting
Client Run
C:\Documents and Settings\Raunak\Desktop\client>
java - Djavax.net.ssl.keyStore="C
:\Program Files\Java\jdk1.6.0_06\jre\lib\security\cacerts" -Djavax.net.ssl.keySt orePassword=changeit -Djavax.net.ssl.trustStore="C:\Program Files\Java\jdk1.6.0_
06\jre\lib\security\cacerts" -Djavax.net.ssl.trustStorePassword=changeit client. ClientMain
Enter your choice:
1. Addition
2. Subtraction
2
Enter the first number for the operation.. 32
Enter the second number for the operation.. 28
Client subtract Port is JAX-WS RI 2.1.6 in JDK 6: Stub for https://localhost:700 2/BasicOperations/BasicOperationService
Result = 4
Result of subtraction is 4