Two-way SSL – Implementation in Pega
This is the final article of the SSL series. In this article, we will see how to implement two-way SSL and how Pega can make use of two-way to secure their web services using keystore and truststore instance.
This is the continuation of my previous article on SSL basics. It is mandatory to go through the below articles for the better understanding.
Same requirement: Assume there are 2 applications (Java application ABC and Pega application XYZ) Pega application is hosting a web service, say GetCaseStatus. So Pega acts as a server and java acts as a client.The Java application passes the case ID as parameter and gets the case details. In the testing environments, pega application is hosted in http protocol, but in the higher environments, the services and more secured and hence https protocol comes into play.As we saw in the previous post, SSL certificates are needed for these secured data transport.
Now the specific requirement for two-way SSL is, the server hosts some sensitive data. These data can only be consumed by the certified consumers. In such case, two-way SSL is the ideal solution. Client needs to be authenticated before opening up the SSL tunnel.
Let’s see the steps involved in two-way SSL.
Step 1: Client sends a REST service call to server requesting the case details.
Step 2: Server first responds with sending the certificates from its keystore where it stores its certificate. It’s public certificate. The client validates the server certificate if it is stored in its own trust store. If yes, the server can be trusted. If not, the connection fails.
Step 3: Once the client validates the server, then client sends its certificate chain for validation.
This should be validated by the server in its keystore. This is specific step for two-way SSL
Step 4: Once the server trusts the client and client trusts the server, then the connection is established and the data can be transferred.
This is the basics behind two-way SSL.
Let’s start with implementing two-way SSL
As we saw in the previous post, let’s update the connector attributes in the server.xml file 😊
Step 1: Locate and open the server.xml file
Under tomcat -> conf
Step 2: Add an attribute clientAuth and set its value to true.
This change will implement the two-way authentication, It means the client should also be authenticated or in other ways, client should also be trusted by the server.
Step 3: Save the server.xml file and restart the server.
Now, two-way SSL comes into picture.
Launch the pega designer studio URL
Here comes the pain!! (my biggest pain in solving this, only my server knows how many times I restarted trying different google solutions, eventually found the solution is simple, typical story of a developer 😉)
Client authentication fails!! Because client provide the certificate and the same must be validated by the server. To solve this, we need to create a client certificate and import the .p12 file in the browser!
In our scenario, browser is the client accessing the server, pega tomcat server.
Again, the overview of SSL handshake
The below picture shows the steps involved in SSL handshake.
(1) “client hello” – contains the cryptographic information that client supports.
(2) “server hello” – Server responds with its digital certificate (private key) along with the trusted CA s (this is applicable only for two-way SSL)
(3)Verify server certificate – client verifies the server certificate.
(4) Client key exchange – we know that SSL data are encrypted. Client generates random string that is used to compute the secret key for encrypting message data.
(5) Client certificate request – This step is applicable only for two-way SSL where the client sends the certificate for verification.
(6) Verify client certificate – server verifies the client certificate using its public key
(7) & (8) once everything goes good, messages get transferred successfully.
Create and sign client certificates
The steps follow the same steps as the server certificate generation.
Step 1: create a private key for your client.
Execute the below command.
genrsa -des3 -out C:UserspremgKeysclient.key 1024
Step 2: You need to create a certificate signing request. We need to do this to get signed by our own CA certificate, which we created in the first post
req -new -key C:UserspremgKeysclient.key -out C:UserspremgKeysclient.csr
Step 3: Sign your client certificate with your own CA.
x509 -req -days 360 -in C:UserspremgKeysclient.csr -CA C:UserspremgKeysca.crt -CAkey C:UserspremgKeysca.key -CAcreateserial -out C:UserspremgKeysclient.crt
Verify the client certificates are created rightly.
Step 4: Create a new PKCS12 file format for the client certificate. This should be uploaded to the browser.
Execute the below command
pkcs12 -export -in C:UserspremgKeysclient.crt -inkey C:UserspremgKeysclient.key -out C:UserspremgKeysclient.p12
Important note: This is the security part. Now whoever has this PKCS12 file, can be considered as the approved clients
Step 5: Now install the client certificates to browser.
Go to chrome, settings -> Manage certficates -> Import
Upload the file – client.p12 and make it personal certificate.
Chrome browser uses this location to send the client certificate.
Note: Please import it to personal category. Do not put it in the trusted category like I did for days 😉
Step 6: Now restart your chrome browser and launch the URL again (keep an eye on the logs)
Client presents with the certificate we installed.
Click ok and proceed.
Your pega application will be launched 😊
Step 7: check on the log file.
Note: Add the command for debugging SSL in the Catalina.bat file – set “JAVA_OPTS=%JAVA_OPTS% -Djavax.net.debug=:handshake”
Check one-way SSL post for more details
You will see everything went good without any error.
Two-way SSL testing
Step 1: Let’s continue right from the steps we used for one-way SSL.
From the postman, hit the same https URL.
https://localhost:8443/prweb/api/v1/nodes/75c08abad559cc44cda33fccd5ddfaf0/agents
Step 2: Service failed. You know why?
Here postman is the client and it should validate its certificate.
Step 3: Same like previous post, switch to certificates tab and add the client certificate client.p12 file.
Click Add, you will see the client certificates added.
Step 4: Now from postman, hit the same URl again.
Thumbs up!!
Final steps on testing for two-way SSL using pega client.
I am going to use the same Service-REST and Conect-REST we saw in the previous post.
For now, I am going the use the same localhost personal edition as both client and server also the same Service-REST I used for one-way SSL.
For server side
Keystore – which contains the public key, private key certificates – stays in conf.keystore location.
Truststore – contains all the trusted CAs – stays in JRElibsecuritycacerts
For client side
We can specify both in the Connect-REST rule.
Pre-requisites ( I performed the same steps in my previous article)
a) Build a new connect-REST using the wizard to consume the service
b) In the Connect-REST, provide the basic authentication profile and keep both the truststore and keystore as empty in the security settings.
c) For testing purpose associate a data layer and data page with the connect-REST during wizard creation.
Step 1: Run the data page with the node ID as input parameter.
Remember, the connector pega is the client, so it should show some client certificate for verification and since we didn’t import the client certificate error pops up.
Step 2: Create a new keystore for client in tomcat server
First let’s create a keystore in the tomcat to store the client details.
We already have a .p12 file. Use the below command
keytool -importkeystore -srckeystore C:UserspremgKeysclient.p12 -srcstoretype PKCS12 -destkeystore C:PRPCPersonalEditiontomcatconfclientkeystore.jks -deststoretype JKS
Note: my destination path is directly on the tomcatconf
This will create a new keystore for the client certificate.
Note: Again, I want to mention that if I had two pega instances, then clientkeystore.jks will be in one pega instance (client) and the keystore.jks will be in another pega server instance. For this demo, I am using only one and thus you see both. Please do not get confuse.
Step 3: Create a new keystore instance in pega and refer to the client keystore file.
Step 4: Update the connect-REST rule by pointing the keystore to this instance.
Step 5: Now run the data page and see the magic!
Perfect 😊
In the SSL handshake part, please browse some Google articles and learn how it is implemented. They follow a standard standard and most actions reside within the SSL engine, like signing the client request with server’s pubic key etc.
I didn’t go through those topics in details, but things happen under the hood.
Enable the SSL handshake debug log and checkout the log entries on every SSL request. You will see the sequential steps.
Hope you guys learned something new in SSL.