Export private key from Salesforce in Java Keystore format and convert to PEM format

Today I needed to use the JWT flow to get an access token from Salesforce to use the Salesforce API in a server to server scenario. To do that you need a private key (usually in PEM format) for the client and the corresponding public key in a keystore on the Salesforce side. Being lazy I simply generated a public / private key pair in Salesforce with an exportable private key and exported the keystore.

Since Salesforce exports the keystore in Java Keystore Format (JKS) I need to work with the Java keytool and openssl to export the private key. Below are the steps. The landing_site_pk alias below is the same of the private key entry in the keystore and the API name of the keystore in Salesforce and Passw0rd is the password specified when exporting the keystore. Adjust as needed.

$ keytool -importkeystore -srckeystore ./00D090000046d3F.jks -srcstorepass Passw0rd -srcalias landing_site_pk -destalias landing_site_pk -destkeystore ./00D090000046d3F.p12 -deststoretype PKCS12 -deststorepass Passw0rd -destkeypass Passw0rd
Importing keystore ./00D090000046d3F.jks to ./00D090000046d3F.p12...

$ openssl pkcs12 -in ./00D090000046d3F.p12 -nodes -nocerts -out 00D090000046d3F.pem
Enter Import Password:
MAC verified OK

$ cat 00D090000046d3F.pem
Bag Attributes
friendlyName: landing_site_pk
localKeyID: 54 69 6D 65 20 31 36 30 36 33 39 30 30 35 36 38 30 38
Key Attributes:
-----BEGIN PRIVATE KEY-----
MIIEuwIBA....bTe+Hzyz
-----END PRIVATE KEY-----

Generate own Certificate Authority for testing custom Domains with Salesforce Communities

I had a need to test custom domains with Salesforce Communities and be able to log into those communities. When authenticating to a Salesforce Community an encrypted connection (meaning SSL) is required so I needed an easy and free way to generate certificates for my domains The solution was using openssl for the signing and Firefox for the testing as the latter comes with its own Trust Store. Lately many browsers has become very picky about what root certificates are trusted making this kind of testing harder.

Below are the steps I used:

Generate a private key for the root certificate authority:
openssl genrsa -des3 -out rootCA.key 4096

Selg-sign and create a certificate with the private key:
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Convert the certificate to PEM format for import into the Firefox Trust Store:
openssl x509 -in rootCA.crt -pubkey > rootCA_publickey.pem

Now in Salesforce Setup using “Certificate and Key Management” use “Create CA-Signed Certificate” and fill in the form. Then download the Certificate Signing Request (CSR) to your machine and then sign the CSR:
openssl x509 -req -in my_csr_file.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out my_csr_file.crt -days 365 -sha256

Back in Salesforce on the key/pair created above use “Upload Signed Certificate” and pick the my_csr_file.crt signed above.

Now the certificate may be mapped to a custom domains (under “Domains”) having Salesforce terminate the SSL connection.

Generate a Java Keystore (JKS) which is importable in Salesforce

Salesforce only supports the Java Keystore (JKS) format for importing private/public key pairs (with certificate) into a Salesforce org. Certificates and private/public keypairs are important when using Json Web Tokens (JWT’s) for integration using outbound flows as the JWT needs to be signed using the private key.

If working with Named Credentials for an outbound JWT token flow you need to import a private/public key into Salesforce using “Certificate and Key Management” in Setup. In the latter case you could also use a self-signed certificate generated in Salesforce.

What ever you do you need a valid keystore. Below are the commands I use to generate a private/public keypair with openssl and then use keytool (the Java keystore tool) to import into a Java keystore valid for Salesforce.

# generate private/public keypair
openssl req -newkey rsa:2048 -nodes -keyout private_key.pem -x509 -days 365 -out certificate.pem

# write certificate in binary file (some sytems need binary format)
openssl x509 -outform der -in certificate.pem -out public_key.der

# get the public key from the certificate
openssl x509 -in certificate.pem -pubkey > public_key.pem

# import certificate into Java Key Store (JKS)
# !!! Be sure to trust the certificate - otherwise it's not imported
keytool -importcert -file certificate.pem -keystore keystore.jks -alias mycertificate -storetype jks

# create a PKCS12 keystore with private/public keypair
openssl pkcs12 -inkey private_key.pem -in certificate.pem -export -out keystore.p12 -name mykey

# import keypair into Java keystore
keytool -importkeystore -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -destalias mykey -srcalias mykey

Using Tomcat APR (Apache Native Runtime) on Mac

I had to document some steps using the Apache Portable Runtime (APR) and TLS configuration and for that needed APR on my Mac. I couldn’t really make it work at first but after fiddling a bit I figured it out. There are the steps in bullet form:

Download APR and compile

  • Download APR from Apache (http://apr.apache.org/). I downloaded v. 1.5.2.
  • Compile in Terminal.
    • CFLAGS=’-arch x86_64′ ./configure
    • make
    • make test
    • make install

Install OpenSSL with headers

The OpenSSL on Mac doesn’t come with the header files so you cannot compile the Tomcat native library by default. To fix that use Homebrew to install a new version of OpenSSL first.

  • Install Homebrew per instructions on the website
  • brew install openssl

Compile Tomcat native library

The Tomcat native library is supplied with the Tomcat download. My Tomcat was v. 8.0.17. Steps as below:

  • cd Tomcat8.0.17/bin
  • gunzip tomcat-native.tar.gz
  • tar xf tomcat-native.tar
  • cd tomcat-native-1.1.32-src/jni/native
  • CFLAGS=’-arch x86_64′ ./configure –with-apr=/usr/local/apr –with-ssl=/usr/local/opt/openssl
  • make
  • make install

Configure Tomcat to use APR

This step is basically just to make sure that the Tomcat native library is on the Java Library path. Do as follows:

  • cd Tomcat8.0.17/bin
  • vi setenv.sh
  • Add text: JAVA_OPTS=”-Djava.library.path=/usr/local/apr/lib”

Now when you run Tomcat using catalina.sh you should see a line like below stating what version of the native library was loaded.

15-May-2016 18:14:01.106 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent
     Loaded APR based Apache Tomcat Native library 1.1.32 using APR version 1.5.2.

Further reading:

An important tool results from the whole POODLE/SHA-2 debacle

My stance on the POODLE / SHA-2 issues with Domino is well known and I haven’t been holding anything back. And now – after a while – IBM is starting to release the promised tools to lay the foundation for SHA-2 signature support and TLS 1.0 support on IBM Domino. As part of my IBM Support Updates today I saw and entry called “Planned SHA-2 deliveries for IBM Domino 9.x“. This is a technote outlining how IBM is bringing TLS 1.0 and SHA-2 support. This is all well and good and great that IBM starts to deliver on its promises.

But that’s not all… And by far the most interesting thing to find in that technote.

Burried within this technote is a mention of a tool called kyrtool which replaces iKeyman as the way to work with the KYR keystore file used by IBM Domino. It’s a command line tool and allows for import of standard x509 certificates generated using OpenSSL or similar and produces a KYR and a STH (stash) file as the result. There is documentation about the tool in the wikis (Generating a keyring file with a self-signed SHA-2 cert using OpenSSL and kyrtool). As an added bonus the examples with OpenSSL is done on Dave Kerns paranoia Linux box (dskern@paranoia).

The release of this tool is very good news and cannot be overstated and in my eyes far overshines the support for TLS 1.0 and SHA-2 as it allows administrators to work with the KYR files on Windows versions newer than Windows XP. It ever supports win32, win64, linux32 and linux64. How do you like them apples?

Thank you IBM.