One-way SSL – Implementation in Pega
In this blog article, we will see how to implement one-way SSL and how Pega can make use of one-way to secure their web services using keystore instance.
This is the continuation of my previous article on SSL basics.
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 article, SSL certificates are needed for these secured data transport.
The above picture depicts only the very high-level architecture. At the end of this Post, I will explain it in very detail😊
Let’s see the steps involved in one-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: I purposefully crossed down the third step, where the client needs to be authenticated with the server. This is specific to two-way SSL. This is not the step in one-way SSL.
So, in one-way SSL, only the server should be authenticated or trusted by the client.
Step 4: Once the client trusts the server, then the connection is established and the data can be transferred.
So, the first question is how tomcat server knows if needs to implement one-way or two-way SSL?
You need to 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 false.
This change will implement the one-way authentication. It means client authentication is not required.
Step 3: Save the server.xml file and restart the server.
Now, one-way SSL comes into picture.
Also, we came across two terms – Keystore and truststore.
What is keystore?
– It is a repository of security certificates and holds the public key, certificates and private keys.
– It can contain or more certificates uniquely identified by the alias name.
We already created a server keystore in the previous post under tomcat/conf directory.
What is Truststore?
– Again, it is also a repository that stores the certificates that can be trusted.
– It doesn’t store any private key, instead stores the certificates from all the trusted CAs.
– By default, the java package comes with default truststore repository called cacerts file. It usually resides under JRElibsecuritycacerts
Using keytool, you can look into the default CA that comes with cacerts file.
Note: Usually the trust for each host/domain/website will be decided based on which CA approved the certificates
Switch to the JDKbin folder and execute the below command
keytool -list -keystore C:PRPCPersonalEditionjre1.8.0_121libsecuritycacerts
By default, 104 CA authorities are trusted by this JRE.
In the previous post, we saw the default shipped trusted CAs for the operating system windows / chrome browser.
Note: The java applications can have their own truststore in different location.
How truststore and keystore can be related in Pega?
We understood truststore and keystore and just repositories that the stores the keys.
In pega, we have a single data instance called Keystore that can serve as both keystore and truststore
What is a keystore instance?
– Keystore instance can point to a keystore file that stores the keys and certificates for HTTPS connection.
– Mostly used in conjunction with web services.
– It belongs to security category.
Via WS security profile for SOAP connectors and directly in the REST connectors.
In these posts, I will concentrate only on REST. WS security profile needs a dedicated post!
Let’s create a new keystore instance.
Step 1: Records -> Security -> Keystore -> Create new
Step 2: Create and open.
You have lots of option to decide the keystore location.
In the Key management system (KMS) block, you can use the keystore stored in the external location like Amazon etc.
In the Keystore block, you can either upload a file or refer to a keystore via filepath, URL or by using data page.
Based on your selection on the keystore location, the other configuration points become visible.
Keystore type – There are different keystore types like JKS, KEY etc.
Remember on creating a jks file, we always use a password. Specify the password in the keystore password field. My password will be changeit
All the configuration points in the keystore instance are pretty simple and straight forward 😊.
You may get a question here like, what happen if you upload a JKS file in the keystore instance? Will it get saved into the tomcat keystore or truststore files?
Let’s see it in action.
I am uploading the server JKS file to the newly created keystore instance.
Save the instance, pega validates the keystore with the passphrase.
It indirectly means, it decrypts/encrypts the key store entries and associate with the key store instance.
So, the answer is the file will not be saved automatically to the tomcat keystore file.
If you already have a keystore file, then prefer referring the file location from the keystore instance.
How to configure one-way SSL?
Let’s start with steps involved in one-way SSL handshake.
Pre-requisite: Make sure you disabled clientAuth in the server.xml file. (we already did that in the previous post)
How to debug the SSL handshake?
Step 1: Locate and open the file Catalina.bat using notepad++. tomcat->bin->Catalina.bat
Step 2: Add the debug command for SSL handshake.
set “JAVA_OPTS=%JAVA_OPTS% -Djavax.net.debug=:handshake”
Note: Make sure you add it in a place that doesn’t fall inside any loop
Step 3: Save the file and restart the server.
Step 4: Hit the launch URL and keep an eye on the logs – https://localhost:8443/prweb
The below picture shows the steps involved in SSL handshake.
These debugging really helped me in fixing lot of issues!!
Let’s see the steps involved in SSL handshake between client and the server.
(1) “client hello” – contains the cryptographic information that client supports.
(2) “server hello” – Server responds with its digital certificate (public key) along with the trusted CA s (this is applicable only for two-way SSL)
(3) Verify server certificate – client verifies the server certificate from its truststore.
(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.
For more detailed explanation on SSL handshake, please check few google articles.
Let’s test how the one-way SSL behaves
Requirement – Pega hosts a REST webservice and an external application acts as client.
Step 1: We will not create a new REST service, instead we will use the default devops api – AgentRestOperations
The endpoint for this service is – https://localhost:8443/prweb/api/v1/nodes/{nodeId}/agents
Where nodeid can be parameterized.
Step 2: Open the corresponding service package – api to check the security configurations.
By default, TLS and SSL is not enabled for the REST services in this package.
Step 3: Open the Postman and hit the URL with get method.
For now, I am using http instead of https
Remember to pass your node ID as the resource path parameter, along with basic authentication.
Note: To get the node ID, check the clipboard page value pxProcess.pxSystemNodeID
Click send. You will see the valid response.
Now, lets secure this service by enabling the TLS/SSL security in the service package.
Important note: Service package is the place where you can enable the TLS/SSL for your services.
Let’s talk in SSL terms. Here our Pega is the server and the postman is the client application
Step 4: Enable the require TLS/SSL option in the service package.
Step 5: Now change your URL to https and port 8443 and hit the same postman again.
You cannot receive the response. You know why 😊
Since this is a one way SSL, as soon as you hit the server URL, server responds with its public certificate from its keystore.
Now the client, postman should validate the public certificate in its trust store!! But for now, Client don’t have the server certificates and hence the SSL fails.
Let’s add the server certificate in the client truststore.
Step 6: Click on the settings icon in the settings tab.
Note: Make sure you use the postman native app and not the chrome extension!
Switch on the SSL certificate verification.
Postman provides this option, so that if you switch it off, then you can test your https without certificates.
In our scenario, we need to specifically test the SSL certificates, so switch it on 😊
Move to certficates tab in the pop up.
There you will see a block where you can add CA certificates. This is your truststore 😊
BUT… It accepts the certificates in PEM file type ☹
PEM is also one of the formats to present the certificates. In the last post, we created a certificate for our own trust store CA.
We will create a PEM file for our ca.crt file
Now you may get a question, why we didn’t create PEM file for server.crt instead why we are creating for ca.crt?
This is the basis of trust validation. Usually you will see the root certificate is provided by the CAs. So, the trust validation applies first to the root certificates and if it trusted CA, then the issued server can always be trusted. It is the general agreement.
Execute the below command in openssl
x509 -in C:UserspremgKeysserver.crt -out C:UserspremgKeysserver.pem -outform PEM
You will se a ca.pem file created at the keys folder.
Now add the PEM file in the CA certificates block.
Make sure the CA certificates switch is on.
Step 8: Now again hit the same URL from postman.
It works like a charm 😊
We have successfully implemented the one-way SSL using Pega as a service provider.
In the above example, we saw Pega acts as server and postman acts as a client.
Let’s quickly test the other way around.
Pega acts as the client. Since I have only one server available, I am mimicking pega as both server and client. I know it will be bit confusing. Just imagine that the pega server is in different machine 😊
Pre-requisites to use Pega as the SSL client
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.
You see the error. You know the reason why?!
For one-way SSL, client should verify the server certificates in its truststore. But it was not stored yet.
Let’s do it
Step 2: I am going to use the default trust store file
Jrelibsecuritycacerts file
Execute the below command to import the ca.crt file into the truststore
keytool -importcert -file C:UserspremgKeysca.crt -keystore C:PRPCPersonalEditionjre1.8.0_121libsecuritycacerts -alias “1”
Note: Alias 1 was created during the ca certificate creation in the first post.
After you get the success message, verify the certificate entry in your cacerts file using the below command.
keytool -v -list -keystore C:PRPCPersonalEditionjre1.8.0_121libsecuritycacerts -alias “1”
Step 3: Now the restart the server again for the changes to take effect.
Step 4: Once server is started, test the data page again. This time also, don’t provide the keystore or truststore values in the connect-REST rule.
It will work 😊
Now the next question is we didn’t provide any keystore instance in the connect-REST rule, then how it works?
By default, if you don’t provide the keystore or truststore values, Pega use the tomcat default configurations 😊
A tutorial for you guys – Create a new keystore instance and refer to the cacerts file. Now refer the keystore instance to the truststore filed in the connect-REST rule. Play around!
Hopefully, you understood some basics about one-way SSL.