Category Archives: Security

The Resource Owner Password Credential (ROPC) Grant Type

The resource owner password credential grant type is designed as a stop-gap for legacy applications. Should only be used temporarily until the migration of the application to OAUTH is complete. This grant type should never be used anymore. This type can request for offline_access scope (i.e. to request for refresh token).

  1. Use the token end point to do post request for the access token with the following headers:

    Content-Type = application/x-www-form-urlencoded

    And with the following form data:

    grant_type = password
    client_id = the one used from step 1.
    client_secret = 
    username = 
    password = 
    scope = (Optional) what permision wanted. If not specified, default permission will be given.
    state = (Optional) value to echo to us.

    Expected Response

    {
    "access_token" : <ACCESS_TOKEN>,
    "token_type" : "Bearer",
    "expires_in" : 3600,
    "scope" : <The scope allowed by the server>
    }
  2. Call the API with the authorization header like the following syntax:

    Bearer <ACCESS_TOKEN>

Related Post
KEYCLOAK – JWT GENERATION – PASSWORD GRANT TYPE

Keycloak – Realm – OpenID Configuration

The open id configuration exposes some information like the following:

  • Authorization endpoint
  • Token endpoint
  • Supported grant types
  • Supported response types
  • Supported response modes
  • Supported claims
  • Supported scopes

Use the following address syntax to find-out the OpenID configuration:

<KEYCLOAK_ADDRESS>/realms/<TARGET_REALM>/.well-known/openid-configuration

Example

Given

Token Value
KEYCLOAK_ADDRESS http://localhost:8080
TARGET_REALM test

The OpenID configuration would be:

http://localhost:8080/realms/testrealm/.well-known/openid-configuration

Keycloak – JWT Generation – Password Grant Type

Pre-requisite

  • Keycloak 19^1

Creating a New Client and User

  1. Sign in to keycloak admin console using the following address:

    Must know a valid credential.

    http://localhost:8080/admin/

  2. Switch or create a realm that is NOT a master realm (i.e. leave the master realms for keycloak usage only), like the following (i.e. jwtrealm):
    jwt-realm

  3. Create a new client as follows:

    1. Ensure that OpenID Connect is the Client type.

    2. Provide a Client ID (e.g. jwtclient).

    3. Click the Next button.

      client-general-settings

    4. Enable the Client authentication.

    5. In the Authentication flow, unselect the standard flow.

    6. Click the Save button.

      client-capability-config

  4. Create a new user as follows:

    1. Fill-in the username field (e.g. testuser).

    2. Click the Create button.

      user-create

    3. Click the Credentials tab.

    4. Click the Set password button.

    5. Fill-in the Password field.

    6. Fill-in the Password confirmation field.

    7. Turn-off temporary.

    8. Click the Save button.

      user-password

    9. Click the Save password button.

Using Postman for Testing

  1. Create a post request to the following address format:

    http://localhost:8080/realms/<TARGET_REALM>/protocol/openid-connect/token

    Example

    Using the jwtrealm as the TARGET_REALM (i.e. configured in the previous section).

    http://localhost:8080/realms/jwtrealm/protocol/openid-connect/token

  2. Click the Body tab.

  3. Select x-www-form-url-encoded.

  4. Add the following entries:

    Key Value Comment
    client_id jwtclient This is the client configured earlier.
    grant_type password This is for direct access grant type.
    client_secret <Client secret> This can be found in the jwtclient (i.e. configured earlier) client credentials tab.

    client-secret

    scope openid The openid scope is required; to indicate that the application intends to use OIDC to verify the user's identity.
    username testuser This is the user configured earlier.
    password <password> This is the password for the user that is configured earlier.
  5. Click the Send button.

    postman-request

Success Output

The success output is in the following format.

{
    "access_token": "The access token.",
    "expires_in": "Access token expiration.",
    "refresh_expires_in": "Refresh token expiration",
    "refresh_token": "The refresh token.",
    "token_type": "Bearer",
    "id_token": "The ID token.",
    "not-before-policy": 0,
    "session_state": "The session state.",
    "scope": "openid profile email"
}

You paste the encoded token to the following website to decode its content:

https://jwt.io/

Invalid Credential Output

{
    "error": "invalid_grant",
    "error_description": "Invalid user credentials"
}

Related Post
THE RESOURCE OWNER PASSWORD CREDENTIAL (ROPC) GRANT TYPE

Authorization Code Grant Type

The authorization code grant type is designed for confidential clients (e.g. websites with a server back end) that can keep a secret. This type can request for offline_access scope (i.e. to request for refresh token).

  1. Use the authorization end point to request the authorization code with the following query parameters:

    response_type = code 
    client_id = the client unique code
    redirect_uri = redirection URL.
    state = (Optional) value to echo to us.
    scope = (Optional) what permision wanted. If not specified, default permission will be given.
    response_mode = (Optional) query

    A login form will be displayed if not yet filled-up before.

    Expected Response

    The redirect_uri with the following query parameters:

    code = The authorization code
    state = state value if given.
  2. Use the token end point to do post request for the access token with the following headers:

    Content-Type = application/x-www-form-urlencoded
    Authorization = Basic <CREDENTIAL>

    And with the following parameters:

    grant_type = authorization_code.
    code = The authorization code from step 1.
    redirect_uri = The used from step 1.

    Expected Response

    Header

    Content-Type: application/json
    
    {
    "access_token" : <ACCESS_TOKEN>,
    "token_type" : "Bearer",
    "expires_in" : 3600,
    "scope" : <The scope allowed by the server>
    }
  3. Call the API with the authorization header like the following syntax:

    Bearer <ACCESS_TOKEN>

Private Signing a CSR

Signing the CSR

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

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

  2. Create a v3.cnf file using the following template:

    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Self-signed Certificate"
    
    [ alternate_names ]
    
    DNS.1       = <DNS_1>
    #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
    # DNS.7       = 127.0.0.1
    
    # IPv6 localhost
    # DNS.8     = ::1

    Replace the following fields on the template:

    Field Name Description
    DNS_<INDEX> Identify the DNS names from the CSR.

    Example:

    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Self-signed Certificate"
    
    [ alternate_names ]
    
    DNS.1       = www.ronella.xyz
    #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
    # DNS.7       = 127.0.0.1
    
    # IPv6 localhost
    # DNS.8     = ::1
  3. Generate a CA private key and certificate pair. The following link can help:
    PRIVATE CERTIFICATION AUTHORITY (CA)

  4. Once you have the pair (i.e. key is ca.key.pem and the certificate is ca.cert.crt), sign the CSR using the following command:

    openssl x509 -req -days 365 -sha256 -in domain.csr -extfile v3.cnf -CA ca.cert.crt -CAkey ca.key.pem -CAcreateserial -out domain.crt

Viewing the generated certificate from CSR

  1. View the signed certificate using the following the command:

    openssl x509 -in domain.crt -text

Certificate Signing Request (CSR)

Generating a CSR

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

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

  2. Create a domain.cnf file using the following template:

    [ req ]
    default_bits        = 2048
    default_keyfile     = private.pem
    distinguished_name  = subject
    req_extensions      = req_ext
    x509_extensions     = x509_ext
    string_mask         = utf8only
    
    [ 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 (eg, section)
    organizationalUnitName_default = <ORGANIZATIONAL_UNIT>
    
    commonName          = Common Name (e.g. server FQDN or YOUR name)
    commonName_default      = <YOUR_NAME>
    
    emailAddress            = Email Address
    emailAddress_default        = <YOUR_EMAIL_ADDR>
    
    # Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
    [ x509_ext ]
    
    subjectKeyIdentifier        = hash
    authorityKeyIdentifier    = keyid,issuer
    
    basicConstraints        = CA:false
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Self-signed Certificate"
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:false
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Private Certificate"
    
    [ 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
    # DNS.7       = 127.0.0.1
    
    # IPv6 localhost
    # DNS.8     = ::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     = private.pem
    distinguished_name  = subject
    req_extensions      = req_ext
    x509_extensions     = x509_ext
    string_mask         = utf8only
    
    [ 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 (eg, section)
    organizationalUnitName_default = IT Department
    
    commonName          = Common Name (e.g. server FQDN or YOUR name)
    commonName_default      = www.ronella.xyz
    
    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
    
    basicConstraints        = CA:false
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Self-signed Certificate"
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:false
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName          = @alternate_names
    nsComment           = "Private Certificate"
    
    [ 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
    # DNS.7       = 127.0.0.1
    
    # IPv6 localhost
    # DNS.8     = ::1
  3. Generate a private key using the following command:

    openssl genrsa -out domain.key.pem 2048
  4. Generate the CSR using the private key with the following command:

    openssl req -new -key domain.key.pem -nodes -out domain.csr -config domain.cnf

Viewing the Generated CSR

  1. View the generated CSR using the following command:

    openssl req -text -noout -verify -in domain.csr

Private Certification Authority (CA)

Create the 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 a ca.cnf file using the following template:

    [ req ]
    default_bits        = 2048
    default_keyfile     = private.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 (eg, section)
    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_ADDR>
    
    # Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
    [ x509_ext ]
    
    subjectKeyIdentifier        = hash
    authorityKeyIdentifier    = keyid,issuer
    
    basicConstraints        = CA:TRUE
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
    nsComment           = "Private CA"
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:true
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
    nsComment           = "Private CA"

    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 or anything that represents you as a CA.
    YOUR_EMAIL_ADDR Your email address.

    Example:

    [ req ]
    default_bits        = 2048
    default_keyfile     = private.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 Company
    
    organizationalUnitName         = Organizational Unit (eg, section)
    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 CA APR 2021
    
    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
    
    basicConstraints        = CA:TRUE
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
    nsComment           = "Private CA"
    
    # Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
    [ req_ext ]
    
    subjectKeyIdentifier        = hash
    
    basicConstraints        = CA:true
    keyUsage            = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
    nsComment           = "Private CA"
  3. Generate a private key using the following command:

    openssl genrsa -out ca.key.pem 2048
  4. Generate a certificate with a validity of 10 years from the private key using the following command:

    openssl req -x509 -sha256 -new -nodes -key ca.key.pem -days 3650 -out ca.cert.crt -config ca.cnf

Viewing the generated certificate

  1. View the generated certificate using the following command:

    openssl x509 -in ca.cert.crt -text

Generating a Self-signed CA Certificate for JSON Web Token (JWT) for Java

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. Generate an rsa private key using the following:

    openssl genrsa -aes256 -out jwt.private.pem 2048
  3. Generate the public key from the private key using the following:

    openssl rsa -pubout -in jwt.private.pem -out jwt.public.pem

    The public key generation is just to show how to generate it. It is not used in the java keystores. This step can be skipped.

  4. Generate a self-signed CA from the private key with 1 year validity using the following template:

    openssl req -key jwt.private.pem -new -x509 -sha256 -days 365 -subj "/C=<2_LETTER_COUNTRY_CODE>/ST=<STATE_NAME>/L=<CITY_NAME>/O=<ORGANIZATION_NAME>/OU=<ORGANIZATIONAL_UNIT>/CN=<YOUR_NAME>/emailAddress=<YOUR_EMAIL_ADDR>" -out jwt.cert.pem

    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.

    Example:

    openssl req -key jwt.private.pem -new -x509 -sha256 -days 365 -subj "/C=NZ/ST=Wellington/L=Wellington/O=IAG/OU=TopGuns/CN=Ronaldo Webb/emailAddress=ron@ronella.xyz" -out jwt.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 jwt.cert.pem -inkey jwt.private.pem -out jwt.pfx -name "selfsigned"
  6. Store the content of the pfx file to a java keystore using the following command:

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

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

Generating a Self-signed CA Certificate for Java Keystores

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