Certificates

How to Download & Import Certificates into the Java Keystore


Terminology

  1. X.509:  An ITU-T standard based on the ASN.1 standard
  2. Public Key Cryptography Standard (PKCS):  a set of standards published by RSA
  3. Public Key Infrastructure (PKI):  Overall infrastructure based on public & private key cryptography (large prime numbers), usually includes services for issuing, signing, renewing, and revoking certificates
  4. Certificate Authority (CA):  a central authority (server) used to sign and issue certificates, usually public, ex: Verisign, Thawte, etc.
  5. Root CA:  Top-level CA, usually the cert for this is self-signed and the public cert is distributed and installed to all clients, the private keys for this are usually locked away in a secure offline location to prevent compromise
  6. Signing/Intermediate CA:  CA that is actually used to sign certificates
  7. Certificate Revocation List (CRL):  list of revoked certificates
  8. Online Certificate Status Protocol (OCSP):  protocol to detect if a certificate has been revoked
  9. .CSR (Certificate Signing Request):  file extension defining a certification request, it is what is presented to the signing-CA for signing to become a certificate, consists of three main parts: the certification request information, a signature algorithm identifier, and a digital signature on the certification request information, usually encoded in PKCS#10- a Base64 (plain-text) format,
  10. Certificate:  the public key of a server/client/user with accompanying meta-data signed by a trusted authority, used for authentication, also called an X.509 certificate as it defines the format of certificates.  Usually includes an expiration date.
  11. Wildcard certificate:  a certificate that allows any hostname under a specific domain name.  
  12. Subject Alternative Name (SAN):  An X.509 v3 extension allowing for alternative Fully Qualified Domain Names (FQDN)s/domains to be defined, ex: DNS:wikiversity.org, DNS:wikivoyage.org, DNS:wiktionary.org
  13. Full chain:  used to indicate that all certificates up to a root authority are available, ie: root-CA, signing/intermediate-CA, issued server/client/user certificate
  14. .DER (Distinguished Encoding Rules):  is a subset of the X.690 ITU-T standard specifying several ASN.1 encoding formats; also a file extension for certificates (usually binary encoded).  
  15. .PEM (Privacy-enhanced Electronic Mail):  certificate extension, Base64 (plain-text) encoded DER certificate, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"
  16. .CER, .CRT (Certificate):  certificate extension, X.509 format usually or Base64 (plain-text).  
  17. .P7B, .P7C (PKCS#7):  bundled certificate extension, SignedData structure without data, just certificate(s) or CRL(s)
  18. .P12 (PKCS#12) / .PFX (Personal inFormation eXchange):  bundle of (usually full-chain) certificate(s) (public) and private keys (password protected); PFX was a MS IIS standard that was the precursor to P12.  
  19. .JKS (Java Key Store):  Java key store (repository) and extension used to store private keys, public keys, and certificates, created by Java’s keytool binary

Mac OSX and *NIX (Linux, etc.)

1. Open Terminal.app

(warning) IMPORTANT, if you are importing certificates for a JRE that was bundled with your installed software, ie:  NoMagic (Cameo, MagicDraw (MD)), Rhapsody, etc.  please ensure you specify the keystore path for that bundled instance of JRE VS the default as shown above (for MD, you can determine the installed path of JRE by checking Help, About and clicking on the Environments tab; for Rhapsody, open the rhapsody.ini in your installation folder and examine the JavaLocation= var under the [JVM] section).  

2. Using Java keytool, download the certificate (chain) presented by the server you wish to connect to; where host.domain.tld = the FQDN of the server you wish to connect to, ie: repo1.company.com, and port = the port on which SSL/TLS is enabled:  

keytool -printcert -rfc -sslserver host.domain.tld:port > ~/host.domain.tld_full-chain.pem

(info) Note, keytool should be automatically installed and symlinked from /usr/bin/keytool to your Java bin directory when you install Oracle Java.  If not, prefix $JAVA_HOME/bin to the command above. 

3. Open the file in a text editor. 

4. If there's one certificate, skip to step 6.  If there are multiple certificates (ie: a certificate chain), split them apart into separate files named host.domain.tld_part-a...z; where host.domain.tld = the FQDN of the server you connected to.  The below command will do this for you automatically:  

split -a1 -p '-----BEGIN CERTIFICATE-----' ~/host.domain.tld_full-chain.pem ~/host.domain.tld_part-

(warning) Note, on Linux split does not support a -p option so use csplit -f ~/host.domain.tld_part- ~/host.domain.tld_full-chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}' instead. 

5. Use Java keytool to inspect each cert you split; where host.domain.tld = the FQDN of the server you connected to and n = a...z.  The certificates should be ordered from most specific (ie: the server cert) to the issuing root CA's (self-signed) certificate:  

keytool -printcert -file ~/host.domain.tld_part-n.pem

6. Import one ore more of the certificate(s) you would like your Java Key Store (JKS) to trust, where <host.domain.tld|domain.tld_CA|tld_CA> = a memorable all-lowercase alias for the certificate being imported, (warning) only a-z and - (hyphen) characters allowed, ie: mydomain-root-ca, or myserver and $JAVA_HOME = an environment variable specifying where Java's base home directory is (on a Mac this is usually something like  /Library/Java/JavaVirtualMachines/jdk<version>.jdk/Contents/Home):

sudo keytool -importcert -file ~/host.domain.tld_part-n.pem -alias <host.domain.tld|domain.tld_CA|tld_CA> -keystore $JAVA_HOME/jre/lib/security/cacerts

(info) Note, you may wish to first backup your $JAVA_HOME/jre/lib/security/cacerts file

(info) Note2, if you skipped here from step 4, replace the _part-n suffix with _full-chain in the -file parameter of the command. 

(info) Note3, if enabled, you may be prompted for your sudo password, this is usually your admin password of the machine.  if you are prompted for the Java Keystore password, the default is changeit .



Windows 7,10, 2012(-R2), etc.

1. Open an Administrator Command Prompt (CMD.EXE) in your Java home directory's bin folder, ex:  "C:\Program Files\Java\jre<version>\bin".  

(warning) IMPORTANT, if you are importing certificates for a JRE that was bundled with your installed software, ie:  NoMagic (Cameo, MagicDraw (MD)), Rhapsody, etc.  please ensure you specify the keystore path for that bundled instance of JRE VS the default as shown above (for MD, you can determine the installed path of JRE by checking Help, About and clicking on the Environments tab; for Rhapsody, open the rhapsody.ini in your installation folder and examine the JavaLocation= var under the [JVM] section).

2. Using Java keytool, download the certificate (chain) presented by the server you wish to connect to; where host.domain.tld = the FQDN of the server you wish to connect to, ie: repo1.company.com, and port = the port on which SSL/TLS is enabled:  

keytool -printcert -rfc -sslserver host.domain.tld:port > "%UserProfile%\Downloads\host.domain.tld_full-chain.pem"

(info) Note1, if keytool isn't in your path, either cd to your %JAVA_HOME%/bin dir or prefix it to all subsequent references to this command. 

(warning) If you don't have JAVA_HOME defined in your environment, you may get an error saying JAVA_HOME is not defined.  To confirm, type set and if you do not see JAVA_HOME listed, define it via set JAVA_HOME=<path to JAVA home ex: "C:\Program Files\Java\jre1.8.0_151">.  To have this persist across sessions, add it as a System or User Environment Variable.  

3. Open the file in a text editor.  

(warning) Do not use Word, Textpad, or any "advanced" editor that may insert or try to interpolate the text in it. 

4. If there's one certificate, skip to step 6.  If there are multiple certificates (ie: a certificate chain), split them apart into separate files named host.domain.tld_part-a...z; where host.domain.tld = the FQDN of the server you connected to.  The below commands in a PowerShell (PS) prompt will do this for you automatically:  

$allcerts = Get-Content "$env:UserProfile\Downloads\host.domain.tld_full-chain.pem" -Encoding UTF8 -Raw
$i = 0
[regex]::Matches($allcerts, '(-{5}BEGIN CERTIFICATE-{5}[\s\S]*?-{5}END CERTIFICATE-{5})') | ForEach-Object {
    $i++
    $_.value | Out-file "$env:UserProfile\Downloads\host.domain.tld_part-$i.pem" -encoding ASCII
}

5. Use Java keytool to inspect each cert you split; where host.domain.tld = the FQDN of the server you connected to and n = a...z.  The certificates should be ordered from most specific (ie: the server cert) to the issuing root CA's (self-signed) certificate:  

keytool -printcert -file "%UserProfile%\Downloads\host.domain.tld_part-n.pem"

6. Import one ore more of the certificate(s) you would like your Java Key Store (JKS) to trust, where <host.domain.tld|domain.tld_CA|tld_CA> = a memorable all-lowercase alias for the certificate being imported, (warning) only a-z and - (hyphen) characters allowed, ie: mydomain-root-ca, or myserver  and $JAVA_HOME = an environment variable specifying where Java's base home directory is

keytool -importcert -file "%UserProfile%\Downloads\host.domain.tld_part-n.pem" -alias <host.domain.tld|domain.tld_CA|tld_CA> -keystore %JAVA_HOME%\lib\security\cacerts

(info) Note1, you may wish to first backup your %JAVA_HOME%\lib\security\cacerts file.  

(info) Note2, if you skipped here from step 4, replace the _part-n suffix with _full-chain in the -file parameter of the command. 

(info) Note3, if you are prompted for the Java Keystore password, the default is changeit .