|
#-------------------------------------------------------------------------------# |
| # 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 |