Creating the java keystore and truststore with private key and certificate pair

  1. Download OpenSSL binaries from the following link if you are using windows:

    https://slproweb.com/products/Win32OpenSSL.html

  2. Create an openssl configuration (i.e. openssl.cnf) file using the following template:

    [ req ]
    default_bits        = 2048
    default_keyfile     = privkey.pem
    distinguished_name  = subject
    req_extensions      = req_ext
    x509_extensions     = x509_ext
    string_mask         = utf8only
    
    # The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
    #   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
    [ subject ]
    countryName         = Country Name (2 letter code)
    countryName_default     = <2_LETTER_COUNTRY_CODE>
    
    stateOrProvinceName     = State or Province Name (full name)
    stateOrProvinceName_default = <STATE_NAME>
    
    localityName            = Locality Name (eg, city)
    localityName_default        = <CITY_NAME>
    
    organizationName         = Organization Name (eg, company)
    organizationName_default    = <ORGANIZATION_NAME>
    
    organizationalUnitName   = Organizational Unit
    organizationalUnitName_default = <ORGANIZATIONAL_UNIT>
    
    # Use a friendly name here because it's presented to the user. The server's DNS
    #   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
    #   by both IETF and CA/Browser Forums. If you place a DNS name here, then you
    #   must include the DNS name in the SAN too (otherwise, Chrome and others that
    #   strictly follow the CA/Browser Baseline Requirements will fail).
    commonName          = Common Name (e.g. server FQDN or YOUR name)
    commonName_default      = <YOUR_NAME>
    
    emailAddress            = Email Address
    emailAddress_default        = <YOUR_EMAIL_ADDRESS>
    
    # Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
    [ x509_ext ]
    
    subjectKeyIdentifier        = hash
    authorityKeyIdentifier    = keyid,issuer
    
    # You only need digitalSignature below. *If* you don't allow
    #   RSA Key transport (i.e., you use ephemeral cipher suites), then
    #   omit keyEncipherment because that's key transport.
    basicConstraints        = CA:FALSE
    keyUsage            = digitalSignature, keyEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "OpenSSL Generated Certificate"
    
    # RFC 5280, Section 4.2.1.12 makes EKU optional
    #   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
    #   In either case, you probably only need serverAuth.
    # extendedKeyUsage    = serverAuth, clientAuth
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:FALSE
    keyUsage            = digitalSignature, keyEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "OpenSSL Generated Certificate"
    
    # RFC 5280, Section 4.2.1.12 makes EKU optional
    #   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
    #   In either case, you probably only need serverAuth.
    # extendedKeyUsage    = serverAuth, clientAuth
    
    [ alternate_names ]
    
    DNS.1       = <DNS_1>
    
    # Add more DNS by incrementing the DNS.<SUFFIX> like the following.
    # DNS.2       = <DNS_2>
    # DNS.3       = <DNS_3>
    # DNS.4       = <DNS_4>
    
    # Add these if you need them. But usually you don't want them or
    #   need them in production. You may need them for development.
    # DNS.5       = localhost
    # DNS.6       = localhost.localdomain
    
    # IPv6 localhost
    # DNS.8     = ::1
    
    # IP address using the following:
    # IP.1       = 127.0.0.1

    Replace the following fields on the template:

    Field Name Description
    2_LETTER_COUNTRY_CODE The two letter code of your country.
    STATE_NAME The name of your state.
    CITY_NAME The name of your city.
    ORGANIZATION_NAME The name of your organization.
    ORGANIZATIONAL_UNIT The name of your section in the organization.
    YOUR_NAME Your full name.
    YOUR_EMAIL_ADDR Your email address.
    DNS.<INDEX> Your DNS name.

    Example:

    [ req ]
    default_bits        = 2048
    default_keyfile     = privkey.pem
    distinguished_name  = subject
    req_extensions      = req_ext
    x509_extensions     = x509_ext
    string_mask         = utf8only
    
    # The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
    #   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
    [ subject ]
    countryName         = Country Name (2 letter code)
    countryName_default     = NZ
    
    stateOrProvinceName     = State or Province Name (full name)
    stateOrProvinceName_default = Wellington
    
    localityName            = Locality Name (eg, city)
    localityName_default        = Wellington
    
    organizationName         = Organization Name (eg, company)
    organizationName_default    = My Organization
    
    organizationalUnitName   = Organizational Unit
    organizationalUnitName_default = IT Department
    
    # Use a friendly name here because it's presented to the user. The server's DNS
    #   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
    #   by both IETF and CA/Browser Forums. If you place a DNS name here, then you
    #   must include the DNS name in the SAN too (otherwise, Chrome and others that
    #   strictly follow the CA/Browser Baseline Requirements will fail).
    commonName          = Common Name (e.g. server FQDN or YOUR name)
    commonName_default      = Ronaldo Webb
    
    emailAddress            = Email Address
    emailAddress_default        = ron@ronella.xyz
    
    # Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
    [ x509_ext ]
    
    subjectKeyIdentifier        = hash
    authorityKeyIdentifier    = keyid,issuer
    
    # You only need digitalSignature below. *If* you don't allow
    #   RSA Key transport (i.e., you use ephemeral cipher suites), then
    #   omit keyEncipherment because that's key transport.
    basicConstraints        = CA:FALSE
    keyUsage            = digitalSignature, keyEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "OpenSSL Generated Certificate"
    
    # RFC 5280, Section 4.2.1.12 makes EKU optional
    #   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
    #   In either case, you probably only need serverAuth.
    # extendedKeyUsage    = serverAuth, clientAuth
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:FALSE
    keyUsage            = digitalSignature, keyEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "OpenSSL Generated Certificate"
    
    # RFC 5280, Section 4.2.1.12 makes EKU optional
    #   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
    #   In either case, you probably only need serverAuth.
    # extendedKeyUsage    = serverAuth, clientAuth
    
    [ alternate_names ]
    
    DNS.1       = www.ronella.xyz
    
    # Add more DNS by incrementing the DNS.<SUFFIX> like the following.
    # DNS.2       = <DNS_2>
    # DNS.3       = <DNS_3>
    # DNS.4       = <DNS_4>
    
    # Add these if you need them. But usually you don't want them or
    #   need them in production. You may need them for development.
    # DNS.5       = localhost
    # DNS.6       = localhost.localdomain
    
    # IPv6 localhost
    # DNS.8     = ::1
    
    # IP address using the following:
    # IP.1       = 127.0.0.1
  3. Save the openssl.cnf on your desired location.

  4. Generate the private key and certificate with 1yr validity using the following command:

    openssl req -config openssl.cnf -new -x509 -sha256 -newkey rsa:2048 -keyout privkey.pem -days 365 -out cert.pem
  5. Generate a pkcs12 file from the generated private key and certificate with the selfsigned alias using the following command:

    openssl pkcs12 -export -in cert.pem -inkey privkey.pem -out cert.pfx -name selfsigned
  6. Store the pfx file to a java keystore using the following command:

    "%JAVA_HOME%\bin\keytool" -importkeystore -destkeystore keystore.jks -deststorepass password -deststoretype PKCS12 -srckeystore cert.pfx -srcstoretype PKCS12 -srcstorepass password
  7. Store the certificate to a java truststore using the following command:

    "%JAVA_HOME%\bin\keytool" -import -file cert.pem -keystore truststore.jks -storetype PKCS12 -storepass password -alias selfsigned