Loading...
 

Java SSL

Introduction

SSL

SSL understands many different standards but will generally have the following requirements.

A Certificate Authority (CA) private/public key pair.  Of which the private key is used to sign customer public certificate signing requests (CSR); and the public is used to verify the identity of these signed public certificates.

A private/public key pair (after the CSR is signed).  Used to verify and encrypt communication between 2 end points.  The public key is freely distributed and includes the key ID of the CA public certificate used to create a “train of trust”.

A successful SSL communication requires 3 of these certificates, the private CA key is no longer needed from this point.  The private key stays on the server and decrypts data sent by the public key.  The public key is distributed to anyone who wants it and encrypts data sent to the server.  The CA public key verifies the identity of the server and needs to be installed somewhere in the client machine so as to do this (web browsers have all the standard ones like Verisign pre-installed).

Further security can be added by verifying the client, in which case the, a private key needs to be installed on the client side and the both public keys on the server.

Java

Java Keystore is Java’s implementation of using these certificates for SSL communication between 2+ endpoints.  It accepts 2 types of certificate.

PrivateKeyEntry - each holds very sensitive cryptographic key information, which is stored in a protected format to prevent unauthorized access. Typically, a key stored in this type of entry is a secret key, or a private key accompanied by the certificate “chain” for the corresponding public key. On SDK 1.4.2 and previous versions, keytool only handles private key entry.

TrustedCertEntry - each contains a single public key certificate belonging to another party. It is called a “trusted certificate” because the keystore owner trusts that the public key in the certificate indeed belongs to the identity identified by the “subject” (owner) of the certificate. The issuer of the certificate vouches for this, by signing the certificate.

The keystore won’t accept PEM format certificates, only DER.  So these will need to be converted.  It also won’t accept a standard RSA SSL private key without its matching public key

Examples

A Billing System

server1 communicates with the billing system in Germany using Java keystores with a PrivKeyEntry and a TrustedCertEntry.  The PrivKeyEntry is made up of the private key and a self-signed (by the Billing System Admin) public key pair; and the TrustedCertEntry is the CA public key that verifies it.  So from the Billing System we need an RSA private certificate and its matching x509 self-signed public certificate; and the CA public x509 certificate that signed it.

Checking the certificates

The CA certificate should output as follows:

$openssl x509 -text -noout -in Prod_Public_CA.pem|grep TRUE
CA:TRUE

I would also expect the public_key.pem to have a similar output to the ca_public_key.pem, but with a few extra X509 extensions, a bit more info and the basic constraint being CA: FALSE
root@server1:~# openssl x509 -text -noout -in Prod_Public.pem | grep -A13 “X509v3 extensions”
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Client, S/MIME
Netscape Comment:
Alteon/Nortel Generated Certificate

X509v3 Subject Key Identifier: 

BD:E0:43:17:50:23:4E:AD:32:27:6E:45:E1:1F:91:8F:52:9D:B7:FD
X509v3 Authority Key Identifier:
keyid:AC:35:18:47:86:DC:EE:1D:3F:C6:4D:2F:B4:8E:B9:5F:76:4E:0F:D8
DirName:/C=NZ/ST=New Zealand/L=Auckland/O=Billing System Ltd/OU=IPTO/CN=di.billing.co.nz/emailAddress=ipto@billing.co.nz
serial:00

And only the client_server_private_key.pem to output the following (note rsa instead of x509) - a password will also probably be required:
$openssl rsa -text -noout -in Prod_Private.pem |grep -i private
Private-Key: (2048 bit)
privateExponent:

We can also see if the CA certificate matches the keypair we’ve been given by comparing the KeyIDs

(gbrown@linux1-SysOps)(16:12:01)(certs)
$openssl x509 -text -noout -in Prod_Public_CA.pem | grep -A1 “Subject Key Identifier”
X509v3 Subject Key Identifier:
AC:35:18:47:86:DC:EE:1D:3F:C6:4D:2F:B4:8E:B9:5F:76:4E:0F:D8
(gbrown@linux1-SysOps)(16:12:09)(certs)
$openssl x509 -text -noout -in Prod_Public.pem | grep -A1 “Authority Key Identifier”
X509v3 Authority Key Identifier:
keyid:AC:35:18:47:86:DC:EE:1D:3F:C6:4D:2F:B4:8E:B9:5F:76:4E:0F:D8

Import the certificates into the Java keystore

Convert the certs from PEM to DER

$openssl pkcs8 -topk8 -nocrypt -in Prod_Private.pem -out Prod_Private.der -outform DER

$openssl x509 -in Prod_Public.pem -out Prod_Public.der -outform DER

$openssl x509 -in Prod_Public_CA.pem -out Prod_Public_CA.der -outform DER

Convert and import the Private key into a keystore

copy the attached ConvertKey class to the parent directory, then using the password from /usr/lib/musicstation/billing/NZBilling.properties (on the same server):

$ cd ..

$ java ConvertKey certs/Prod_Private.der certs/Prod_Public.der ./bill_nz_aus.jks ppdi.billing.co.nz

Import the CA public certificate (using the same keystore password).  It can’t verify the identity of this certificate so will ask for confirmation

$keytool -keystore bill_nz_aus.jks -importcert -alias prod_vf -file certs/Prod_Public_CA.der

Enter keystore password:
Owner: EMAILADDRESS=ipto@billing.co.nz, CN=di.billing.co.nz, OU=IPTO, O=Billing NZ Ltd, L=Auckland, ST=New Zealand, C=NZ
Issuer: EMAILADDRESS=ipto@billing.co.nz, CN=di.billing.co.nz, OU=IPTO, O=Billing NZ Ltd, L=Auckland, ST=New Zealand, C=NZ
Serial number: 0
Valid from: Wed Aug 03 00:07:15 BST 2011 until: Sat Aug 02 00:07:15 BST 2014
Certificate fingerprints:
MD5: 5F:12:33:35:C9:12:BD:06:BA:9A:99:E7:E0:F4:44:99
SHA1: AB:82:54:0F:A1:20:20:A8:74:89:8F:AD:EB:19:18:6B:DD:31:CD:B9
Signature algorithm name: MD5withRSA
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: AC 35 18 47 86 DC EE 1D 3F C6 4D 2F B4 8E B9 5F .5.G....?.M/..._
0010: 76 4E 0F D8 vN..
]
]

#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true

Check the Import

There should be a PrivKeyEntry containing the Client private/public keys and a TrustedCertEntry containing the CA public cert.

$keytool -list -keystore ./bill_nz_aus.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

di.bill.co.nz, 05-Aug-2011, PrivateKeyEntry,
Certificate fingerprint (MD5): 78:35:01:BB:D7:D3:27:9C:BE:ED:AB:6C:6A:26:FA:22
prod_vf, 05-Aug-2011, trustedCertEntry,
Certificate fingerprint (MD5): 5F:12:33:35:C9:12:BD:06:BA:9A:99:E7:E0:F4:44:99
$