2

I am a dabbling into Node JS. I got a requirement where Node JS(using 'request' module) had to call Java REST API via HTTPS.

As explained in given URL, I created a CA file (ca.key, ca.pem), certs for server (server1.key, server1.pem) & client (client1.key, client1.pem) and I am able to communicate between two Node JS apps (server & client).

Now I want to access a JAVA REST API running on Apache Tomcat from my Node JS client. So now how can I import my Node JS server keys (server1.key, server1.pem) & ca.pem to Tomcat Keystore? Can I directly include these server1.key, server1.pem & ca.pem into Tomcat or did I had to convert them to .p12 or .jks and import them?

Community
  • 1
  • 1
PrAvEeN
  • 41
  • 1
  • 7

1 Answers1

2

Below is the method I followed for NodeJS to Tomcat communication via HTTPS with self-signed certificate. I saw many solutions online like to make process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; or rejectUnauthorized/strictSSL as false but I thought these may not be valid solutions for proper testing.

This will also eliminate errors like DEPTH_ZERO_SELF_SIGNED_CERT

NodeJS to Tomcat:

Step 1: Certificates & Keystore generation (steps 1 to 4 uses openssl)

  1. Create CA certificate, self sign

    openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 365 -key ca.key -out ca.crt //Provide a valid password during certificate generation

  2. Modify the openssl.cfg/openssl.cnf file in openssl folder as below(generally can be found in openssl/bin folder). (This is to add hostname/IP address to ‘subjectAltName’ in certificates)

    a) Make sure ‘v3_req’ is assigned & uncommented

    req_extensions = v3_req

    b) Then append hostnames under ‘v3_req’ as follows:

    subjectAltName = @alt_names [alt_names] DNS.1 = <hostname of Tomcat server> IP.1 = <IP address of Tomcat server>

  3. Create server key, csr, & sign with our CA

    openssl genrsa -out server.key 1024 openssl req -new -key server.key -out server.csr -config openssl.cfg (Give tomcat server ‘<hostname>’ for field ‘Common Name’) openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extensions v3_req -extfile openssl.cfg openssl x509 -in server.crt -text –noout (optional command to validate created certificate)

  4. Convert the server’s certificate file and private key to PKCS#12

    openssl pkcs12 -export -out certificate.p12 -inkey server.key -in server.crt -certfile ca.crt //Provide a valid password during .p12 generation

  5. Pass ‘ca.crt’ in NodeJS’s ‘request’ call through ‘agent’ property:

    var ca = fs.readFileSync("certs/30112015/ca.crt"); var agent = new https.Agent({ ca: ca }); var opts = { agent: agent }; request(opts, function(err, response, body) { //response handler code } );

  6. Convert PKCS#12 to Java Keystore file (uses java ‘keytool’)

    keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks

  7. Import CA certificate into keystore

    keytool -import -alias root -keystore keystore.jks -trustcacerts -file ca.crt

Step 2: Configuring Tomcat server

  1. copy keystore.jks file to apache-tomcat-8.0.21/conf directory
  2. Add the following connectors in server.xml

    <Connector URIEncoding="UTF-8" connectionTimeout="20000" port="2020" protocol="HTTP/1.1" redirectPort="8099"/> <Connector SSLEnabled="true" clientAuth="false" keystoreFile="C:/apache-tomcat-8.0.21/conf/keystore.jks" keystorePass="password" maxThreads="1000" port="8099" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS"/>

PrAvEeN
  • 41
  • 1
  • 7
  • very helpful thanks. This answer is essentially 99% how to create certificates and how to put them in a Java keystore. It was very good for pointing me in the right direction. The important bit from a node perspective is STEP 5 which I can confirm works. – danday74 Jan 14 '16 at 09:48