Monday, March 6, 2023

jks keytool commands

# 1. Create a Java Key Store (JKS) with Private & Public key pairs using keytool
#
-------------------------------------------------------------------------------#
# Keytool '-genkeypair' option used, in earlier version of keytool '-genkey' option was used which is still supported for backward compatibility
# Following command generates a RSA 2048 bit Public and Private key pair, wraps the public key into an X.509 v3 self-signed certificate signed by SHA256withRSA with a validity period of 365 days, which is then stored as a single-element certificate chain. This certificate chain and the private key are stored in a new keystore 'sample_keystore.jks' entry identified by alias 'sample'.
# Option defaults:
# -alias: mykey
# -keyalg: DSA
# -keysize: 2048 bit (for both RSA and DSA)
# -validity: 90 days
# -storetype: JKS (property value fetched from 'java.security.keystore.type' from Java jdk/jre)
# Ref: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#keytool_option_genkeypair
keytool -genkeypair -v -alias sample -keyalg RSA -keysize 2048 \
-dname "CN=sample.com, OU=apim, O=wso2, L=colombo, ST=western, C=lk" -validity 365 -keypass abcd@1234 -storepass abcd@1234 \
-keystore sample_keystore.jks
# 2. Create a JKS with Private & Public key pairs including SANs, IPs, KeyUsages & ExtendedKeyUsages using keytool
#-----------------------------------------------------------------------------------------------------------------#
# Keytool extension '-ext' option used to provide 'SAN', 'IP', 'KeyUsage' and 'ExtendedKeyUsage'
# Note:
# Using JDKs below JDK15, it is not possible to generate a JKS 'passing wildcard SAN extension' with keytool
# Example, with JDK8, 'dns:*.efs.eu-west-1.amazonaws.com' Or 'dns:test.*.eu-west-1.amazonaws.com' will result in an error
# This has been fixed with JDK15, https://bugs.openjdk.java.net/browse/JDK-8186143
keytool -genkeypair -v -alias sample -keyalg RSA -keysize 2048 \
-dname "CN=sample.com, OU=apim, O=wso2, L=colombo, ST=western, C=lk" \
-ext "san=dns:test.sample.com,dns:test.efs.eu-west-1.amazonaws.com,dns:localhost,ip:127.0.0.1" \
-ext KeyUsage=digitalSignature,keyEncipherment,dataEncipherment,nonRepudiation,keyCertSign \
-ext ExtendedKeyUsage=serverAuth,clientAuth -validity 365 -keypass abcd@1234 -storepass abcd@1234 \
-keystore sample_keystore.jks
# 3. List entries of JKS
#-----------------------#
keytool -list -v -keystore sample_keystore.jks
# 4. Converting a JKS to PKCS12 keystore
#---------------------------------------#
keytool -importkeystore -srckeystore sample_keystore.jks -destkeystore sample_keystore.pfx -deststoretype pkcs12
# 5. Export public certificate from JKS in DER format (binary-encoded format)
#----------------------------------------------------------------------------#
keytool -exportcert -alias sample -file sample.crt -keystore sample_keystore.jks
# 6. Export public certificate from JKS in PEM format (ASCII Base64 human-readble format)
#----------------------------------------------------------------------------------------#
# Additional '-rfc' option need to be passed along with '-exportcert' option to get a pem encoded certificate
keytool -exportcert -alias sample -file sample.pem -keystore sample_keystore.jks -rfc
# 7. Import third-party public certificates to the JKS
#-----------------------------------------------------#
# Third party public certificates are imported as Trusted CA certificates
keytool -import -trustcacerts -alias wso2carbon -file wso2carbon.pem -keystore sample_keystore.jks
# 8. Export private key entry from JKS
#-------------------------------------#
# By default, the JKS key store type doesn't support exporting the Private key entry using the key tool
# Private key entry can be exported by converting the JKS to a PKCS12 key store
# Command for converting JKS to PKCS12 key store can be found in 4
# We will use the PKCS12 key store 'sample_keystore.pfx' and export the private key entry in 'PEM' format using the following OpenSSL command
# Options:
# -nodes: No DES format so the Private key won't be encrypted
# -nocerts: No certificates will be exported at all, only the private key entry
openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts -out sample_keystore_private_key.pem
# 9. Convert the private key entry from 'PEM' encoding to 'DER' encoding
#-----------------------------------------------------------------------#
# By default, OpenSSL command saves the private key entry (encrypted/unencrypted) to the file using the 'PEM' encoding
# We can convert the 'PEM' format to 'DER' format using openssl 'pkey','-inform' and '-outform' options
openssl pkey -in sample_keystore_private_key.pem -inform pem -out sample_keystore_private_key.der -outform der
# 10. Export the Triple-DES encrypted private key entry from the JKS
#-------------------------------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# By default, if the 'encryption algorithm' is not specified explicitly Or the '-nodes' options is not passed, OpenSSL will encrypt the private key entry using '3DES encryption algorithm'
# Following exports the 'PEM' encoded '3DES encrypted' private key entry
openssl pkcs12 -in sample_keystore.pfx -nocerts -out sample_keystore_private_key_default_enc.pem
# 11. Export the 'AES256' encrypted private key entry from the JKS
#---------------------------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# We can explicitly pass the encryption algorithm as an argument (ex: -aes256)
# Apart from using the 'default 3DES algorithm', we can export the encrypted Private key entry by specifying one of the following encryption algorithms.
# AES (aes128, aes192, aes256) => -aes128, -aes192, -aes256
# DES => -des
# 3DES => -des3
openssl pkcs12 -in sample_keystore.pfx -aes256 -nocerts -out sample_keystore_private_key_aes256.pem
# 12. Export the 'RSAPrivateKey' from the JKS
#--------------------------------------------#
# Convert the JKS to PKCS12 key store, command for converting JKS to PKCS12 key store can be found in 4
# Private key entry contains 'Bag Attributes' and 'Key Attributes' apart from the 'Encrypted/Un-encrypted RSAPrivateKey'
# 'RSAPrivateKey' ASN.1 structure defined in 'PKCS#1 (RFC 3447)' allows the private key entry to only contain the private key eliminating the 'Bag Attributes' and 'Key Attributes'.
# 'RSAPrivateKey' contains -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- tags
# Following command will extract an unencrypted RSA private key from the JKS without other attributes
openssl pkcs12 -in sample_keystore.pfx -nodes -nocerts | openssl rsa -out sample_keystore_private_key_rsa.pem
# 13. Extracting 'RSAPrivateKey' from the 'PKCS#8' private key entry
#-------------------------------------------------------------------#
# Older versions of OpenSSL generated private key entry (not RSA private key) in 'PKCS#1', newer versions in 'PKCS#8'
# Following command extracts the 'RSAPrivateKey' from an existing private key entry
openssl rsa -in sample_keystore_private_key.pem -out sample_keystore_private_key_rsa_converted.pem
# 14. Extracting Triple DES encrypted 'RSAPrivateKey' from the 'PKCS#8' private key entry
#----------------------------------------------------------------------------------------#
# RSA private key exported nonencrypted poses a security threat
# Following command extracts a 'RSAPrivateKey' from a 'PKCS#8' private key entry in a Triple DES encrypted format
# Note:
# 'Proc-Type: 4,ENCRYPTED' attribute which shows us the RSA private key entry is encrypted.
openssl rsa -in sample_keystore_private_key.pem -des3 -out sample_keystore_private_key_rsa_des3.pem
# 15. Import a private key entry to JKS
#--------------------------------------#
# It is not possible to directly import private key entry to JKS
# We can import the private key to a 'PKCS12' key store and convert it to a 'JKS' key store
# Following command exports the private key, public certificate and certificate chain as a 'PKCS12' keystore
# Be sure to set an export password to avoid NullPointerException
openssl pkcs12 -export -in <public_cert>.crt -inkey <private_key>.key -chain -CAfile <ca_cert>.crt \
-name "sample.com" -out sample_keystore_pkcs12.p12
# Following command converts the 'PKCS12' key store to a JKS
keytool -importkeystore -srckeystore sample_keystore_pkcs12.p12 -srcstoretype PKCS12 \
-destkeystore sample_keystore_with_imported_private_key.jks -deststoretype JKS -deststorepass abcd@1234
# 16. Generating JKS with 'Secret Key' entry
#-------------------------------------------#
# According to the JKS key store specification, we can't store 'non-PrivateKeys' in a 'JKS' type key store.
# Let's try to generate a JKS with secret key entry using the below command
# Note:
# -genseckey: Option is used to generate the Secret key.
# -keyalg: Argument is used to pass the Secret key algorithm.
# Common secret key algorithms include DES, 3DES, and AES.
keytool -genseckey -alias secretKey -keypass secretKey -keyalg AES -keysize 256 \
-keystore secretKey.jks -storepass secretKey -storetype JKS -v
# The above command will result in an error with an exception
# keytool error: java.security.KeyStoreException: Cannot store non-PrivateKeys
# It is not possible to generate Or import Courtesy: https://techexpertise.medium.com/exploring-key-stores-and-public-certificates-jks-723eb6b32a21

No comments:

Post a Comment