Project

General

Profile

Cryptography Setup Helper

FWD provides a way to automatically configure the X.509 certificates and private keys used by the SSL/TLS protocol. This is done using a self-signed root CA, and is recommended in cases when the certificates are not required to be signed by an explicit, mandatory, root CA (i.e. global for the entire company) or in cases when the root CA is not required to be generated by a certificate authority (like Verisign), which needs to be automatically trusted by all major browsers.

The built-in FWD tool which generates the X.509 certificates and their private keys uses the RSA cryptography tools provided by Bouncy Castle (see https://www.bouncycastle.org/ for more details). This chapter will provide details about how to use this built-in tool to generate the root CA and peer certificates and how to manage the associated private-keys.

Generating the SSL Certificates and Root CA

The built-in tool can be ran in two modes, each case requiring access to a directory file. The easiest way to access this tool is via the ServerDriver's -c argument, which will (re)configure the root CA and associated peer certificates for the directory configured via the associated bootstrap config file or specified via server's configuration arguments; see the Running the Server chapter of this book for more details about the server's startup arguments. The second way is to explicitly the com.goldencode.p2j.security.SSLCertGenUtil, which requires as argument the location of an unencrypted directory file:

java -classpath build/lib/p2j.jar com.goldencode.p2j.security.SSLCertGenUtil <directory-file>

In both cases, a new root CA and new peer certificates will be generated and added to the directory.

When using this tool, it is required that the /security/certificates node has this minimum configuration:

      <node class="container" name="certificates">
        <node class="container" name="cas"/>
        <node class="container" name="peers"/>
      </node>

With this configuration, the SSLCertGenTool will generate a new root CA certificate and peer certificates for all accounts configured with a X.509 authentication mode. Note that if a certificate alias is used for multiple accounts, only one certificate will be generated for this alias.

When running the tool, it is required to provide company-related information, if not already configured in the directory; this information is similar to the information required when generating OpenSSL-style certificates. The console output, when doing this for the first time, looks like:

Initializing service for directory directory.xml...
Reading company configuration...
Organization Unit [OU]: Information Technology
Using 'Information Technology' for [OU] Organization Unit.
Organization [O]: Acme Inc
Using 'Acme Inc' for [O] Organization.
Locality (city, etc) [L]: Atlanta
Using 'Atlanta' for [L] Locality (city, etc).
State or Province Name [ST]: Georgia
Using 'Georgia' for [ST] State or Province Name.
Country Code [C]: US
Using 'US' for [C] Country Code.
Enter validity (years): 10
Using 10 years for validity.

The highlighted text represents an example of the input which can be provided by the administrator. This configuration will be saved in the directory, under the /security/certificates/company/ node:

      <node class="container" name="certificates">
        <node class="container" name="company">
          <node class="string" name="c">
            <node-attribute name="value" value="US"/>
          </node>
          <node class="string" name="l">
            <node-attribute name="value" value="Atlanta"/>
          </node>
          <node class="string" name="o">
            <node-attribute name="value" value="Acme Inc"/>
          </node>
          <node class="string" name="ou">
            <node-attribute name="value" value="Information Technology"/>
          </node>
          <node class="string" name="st">
            <node-attribute name="value" value="Georgia"/>
          </node>
          <node class="integer" name="validityyears">
            <node-attribute name="value" value="10"/>
          </node>
        </node>
      </node>

When this tool is run, if this company configuration already exists in the directory, it will be automatically read and the administrator will not be asked for input: the administrator will just be notified of the used configuration, as in:

Initializing service for directory directory.xml...
Reading company configuration...
Using 'US' for [C] Country Code.
Using 'Atlanta' for [L] Locality (city, etc).
Using 'Acme Inc' for [O] Organization.
Using 'Information Technology' for [OU] Organization Unit.
Using 'Georgia' for [ST] State or Province Name.
Using 10 years for validity.

After determining the company information and number of years the certificates will be valid, this tool will ask some details related to the private keys. This includes the length of the private RSA keys (which defaults to 1024) and the RSA public exponent for these keys (which defaults to 65337):

Enter RSA key strength (in bytes), blank for default (1024): 2048
Using 2048 bytes for RSA private key strength.
Enter RSA public exponent, blank for default (65337): 65337
Using 65337 bytes for RSA public exponent.

with the following constraints:

  • the RSA key strength must be greater or equal than 1024 bytes.
  • the RSA public exponent must be a prime number and it must be carefully chosen, as the security of the private key depends on it. More details about how the public/private keys are computed and how the public exponent is involved can be found by checking the RSA encryption algorithm.

These settings are also saved in the /security/certificates/company/ node:

      <node class="container" name="certificates">
        <node class="container" name="company">
          <node class="integer" name="rsakeystrength">
            <node-attribute name="value" value="2048"/>
          </node>
          <node class="string" name="rsapublicexponent">
            <node-attribute name="value" value="65337"/>
          </node>
        </node>
      </node>

Once all the input is provided, the tool will continue with generating a self-signed root CA certificate; if a root CA does not already exist in the directory, the administrator will be asked for an alias for the new root CA. After this, it will generate peer certificates for the set of aliases configured at the server, user or process accounts:

Enter the root CA alias: acme-root
Generating root CA using [acme-root] alias...
Generating certificate for account with alias [my_server1]...
Generating certificate for account with alias [my_server2]...
Generating certificate for server with alias [batch_program1]...

Before generating the new certificates, the tool needs to determine how to encrypt the private keys for the peer certificates. The administrator can choose from encrypting all private keys using the same random generated password, or using a unique password for each private key (associated with a peer certificate):

Encrypt the private keys using the same password (yes/no): yes

The private keys for the root CA and each peer certificate will be saved under the /security/certificates/private-keys/, for each alias, including the root CA. The root CA's private key will be encrypted using its own password which will not be saved in the directory, while the private keys for the peer certificates will be encrypted either using a master password or distinct passwords, depending on the administrator's input. For each peer private key, the encryption password will be saved in the directory, and will be hex-encoded. After generating the private keys, the administrator will be informed of the password used to encrypt each private key:

Private key for root CA [acme-root] was encrypted using the [ROOT_CA_PRIVATE_KEY_PASSWORD] password and the password was NOT SAVED in the directory.  Losing this password will prohibit using the root CA to issue new certificates.
Adding certificate for alias [acme-root] to the /security/certificates/cas/acme-root node...
Private key for alias [my_server1] was encrypted using the [PASSWORD] password and saved in the /security/certificates/private-keys/my_server1 node.
Use the access:password:keyentry-my_server1 key to set this password in the server's bootstrap config file and delete  the /security/certificates/private-keys/my_server1 node from the directory.
Private key for alias [my_server2] was encrypted using the [PASSWORD] password and saved in the /security/certificates/private-keys/my_server2 node.
Use the access:password:keyentry-my_server2 key to set this password in the server's bootstrap config file and delete  the /security/certificates/private-keys/my_server2 node from the directory.
Private key for alias [batch_program1] was encrypted using the [PASSWORD] password and saved in the /security/certificates/private-keys/ batch_program1 node.
Use the access:password:keyentry-batch_program1 key to set this password in the server's bootstrap config file and delete  the /security/certificates/private-keys/ batch_program1 node from the directory.
Adding certificate for alias [my_server1] to the /security/certificates/peers/my_server1 node...
Adding certificate for alias [my_server2] to the /security/certificates/peers/my_server2 node...
Adding certificate for alias [batch_program1] to the /security/certificates/peers/batch_program1 node...

As seen above, the tool provides information about how to configure the private key encryption password for each alias, via the server's bootstrap config. This can be done via the access:password:keyentry-<alias> configuration, when each peer private key is encrypted with its own password, or via the access:password:masterkeyentry configuration, when all peer private keys were encrypted using the same master password:

<?xml version="1.0"?>
<node type="server">
   <access>
      <password masterkeyentry=”MASTER_PASSWORD_GOES_HERE”/>
   </access>
</node>

or, in case when each peer private key has its own encryption password:

<?xml version="1.0"?>
<node type="server">
   <access>
      <password keyentry-my_server1=”PASSWORD_GOES_HERE”/>
      <password keyentry-my_server2=”PASSWORD_GOES_HERE”/>
      <password keyentry-batch_program1=”PASSWORD_GOES_HERE”/>
   </access>
</node>

After this step, the directory is added a /security/certificates/private-keys/ node, holding the private keys and the encryption password for all aliases, except the root CA:

<node class="container" name="security">
   <node class="container" name="certificates">
      <node class="container" name="private-keys">
         <node class="container" name="acme-root">
            <node class="bytes" name="key-entry">
              <node-attribute name="value" value="ENCRYPTED_AND_ENCODED_PRIVATE_KEY_WOULD_GO_HERE"/>
            </node>
         </node>
         <node class="container" name="my-server1">
            <node class="bytes" name="key-entry">
              <node-attribute name="value" value="ENCRYPTED_AND_ENCODED_PRIVATE_KEY_WOULD_GO_HERE"/>
            </node>
            <node class="bytes" name="key-password">
              <node-attribute name="value" value="ENCODED_ENCRYPTIOPN_PASSWORD_WOULD_GO_HERE"/>
            </node>
         </node>
         <node class="container" name="my-server2">
            <node class="bytes" name="key-entry">
              <node-attribute name="value" value="ENCRYPTED_AND_ENCODED_PRIVATE_KEY_WOULD_GO_HERE"/>
            </node>
            <node class="bytes" name="key-password">
              <node-attribute name="value" value="ENCODED_ENCRYPTIOPN_PASSWORD_WOULD_GO_HERE"/>
            </node>
         </node>
         <node class="container" name="batch-program1">
            <node class="bytes" name="key-entry">
              <node-attribute name="value" value="ENCRYPTED_AND_ENCODED_PRIVATE_KEY_WOULD_GO_HERE"/>
            </node>
            <node class="bytes" name="key-password">
              <node-attribute name="value" value="ENCODED_ENCRYPTIOPN_PASSWORD_WOULD_GO_HERE"/>
            </node>
         </node>
      </node>
   </node>
</node>

For each alias, the private key will be saved under a /security/certificates/private-keys/<alias>/key-entry/ node and the password used to encrypt the private key will be saved under a /security/certificates/private-keys/<alias>/key-password/ node. The saved password will be hex-encoded, and will be used to encrypt the private key, using the AES algorithm.

The next step for this tool is to determine if it needs to save the server certificates in an external key-store; optionally, the administrator can choose to save the root CA certificate in the same store, to use the store as a trust-store:

Save servers' certificates in an external key store (yes/no): yes
Include the root CA certificate, to use this store as a trust store (yes/no)? yes
Enter key store file name: trust-store.store
The servers' certificates [my_server1, my_server2] were saved in the trust-store.store key store, using password 'STORE_ENCRYPTION_PASSWORD'.

The final step is to determine if the root CA's private key needs to be saved in an external key-store. If the administrator enters yes, the tool will ask for the filename holding the root CA's key store:

Save the root CA private key in an external key store (yes/no): yes
Enter key store file name: root-key.store
The root CA's private key and certificate were saved in the 'root-key.store' store.
The key store was encrypted using the [RANDOM_KEY_STORE_PASSWORD] password, while the root CA's private key was encrypted using the [RANDOM_KEY_ENTRY_PASSWORD] password.

If the administrator chooses to save the root CA's private key in an external storage, the root CA's private key can be safely deleted from the directory. Else, the root CA will be available only in the directory.

The tool finishes with these messages:

Done.
WARNING! Any configuration set at the client.xml or server.xml files or via bootstrap config arguments will have priority over the in-directory keys or certificates.
WARNING! The private key encryption passwords for all the account certificates are saved unencrypted in the directory.  The root CA's private key can be safely deleted, if it is not required to issue other certificates using this CA.
WARNING! All private keys are encrypted using the same [MASTER_PASSWORD] password. If needed, delete the 'key-password' nodes from the directory manually, and set this password using the access:password:masterkeyentry bootstrap config at server startup.

where:

  • the first message warns the administrator that any client or server bootstrap configuration will have priority over the in-directory keys and certificates. This means that, if the client or server configuration has explicit key or trust store configuration, the in-directory configuration will be ignored.
  • The second message warns the user that the encryption passwords are saved in the directory, but are not encrypted. This means that the private keys need to be carefully managed, and these need to be protected either via encrypting the directory, encrypting the server bootstrap config file or by carefully managing the permissions for the directory file and bootstrap config files.
  • The final message is shown only in cases when the peer's private keys are encrypted using the same password. In this case, the administrator can remove the passwords used to encrypt the peer private keys from the directory, and pass this password via the access:password:masterkeyentry bootstrap config.

Using the SSLCertGenUtil command line arguments

The FWD tool to generate self-signed or Let's Encrypt certificates can be used in a command-line mode, by specifying input values for certain settings, instead of entering them manually each time. These command-line arguments are:
  • the subject fields for generated certificates, via:
    -S OU="organization unit" 
    -S O="organization" 
    -S L="locality(city)" 
    -S ST="state(province name)" 
    -S C="Country Code" 
    
  • reuse certificate's private key passwords from the directory:
     -P (--reuse-passwords) [YES | NO]
    
  • Encrypt the in-directory private keys using the same password
     -M [YES | NO]
    
  • Reuse root CA from the directory
     -C (--reuse-ca) [YES | NO]
    
  • Sets protection password for the root certificate's private key
     -PKPWD (--private-key-password) VAL
    
  • Indicates if the new root certificate will be loaded from the file system or not, to load an external root certificate:
    • Sets new root certificate PEM file
      -L cert=cert_pem_file.pem 
      
    • Sets new private key associated with the new root certificate PEM file
      -L key=private_key_pem_file.pem
      
    • Sets new root certificate chain PEM file
      -L chain=chain_pem_file.pem
      
  • Sets the path to the directory xml
     -dir VAL
    
  • Sets the alias name to store new root certificate.
    -alias
    
  • Save the account private keys in external key-store(s) (default: YES)
     -EAPK (--export-account-keys) [YES | NO]
    
  • Save the server private keys in external key-store(s) (default: YES)
     -ESPK (--export-server-keys) [YES | NO]
    
  • Save the server certificates in external key-store(s) (default: YES)
     -ESC (--export-server-certs) [YES | NO]
    
  • Include the root CA certificate in the server certificates store as a trust store (default: YES)
     -ICA (--include-ca) [YES | NO]
    
  • The server certificates store (default: srv-certs.store)
     -srvcerts (--server-certs-store) VAL
    
  • Save the root CA private key in an external key store (default: YES)
     -ECAK (--export-ca-key) [YES | NO]       
    
  • The root CA private keys store (default: root-ca-pk.store)
     -cakeys (--root-private-keys-store) VAL
    
  • Save the account private keys in the same key store (default: NO)
     -UCAS (--use-common-account-store) [YES | NO]
    
  • The account private keys common key store
     -cas (--common-account-store) VAL        
    
  • Save the server private keys in the same key store (default: NO)
     -UCSS (--use-common-server-store) [YES | NO]
    
  • The server private keys common key store
     -css (--common-server-store) VAL         
    
  • The RSA key size. (default: 2048)
     -rsa (--rsa-key-size) N
    
  • The RSA public exponent. (default: 65537)
     -exp (--rsa-public-exponent) N           
    
  • To generate public and private certificates for the target alias.
     -bal (--build-alias-certs) VAL
    
  • The ACME client command.
     -acme (--acme-command) [REQUEST | REVOKE | UPDATE_ACME_ACCOUNT | REMOVE_ACME_ACCOUNT]                      
    
  • The ACME server URI.
     -server (--lets-encrypt-server) VAL
    
  • The P2J server identifier.
     -sid (--server-id) VAL
    
  • The web certificate alias.
     -walias (--web-alias) VAL
    
  • The ACME client host IP address.
     -host (--lets-encrypt-client-host) VAL
    
  • The ACME client port that is redirected 443 port accessible for Let's Encrypt ACME server. (default: 0)
     -port (--lets-encrypt-client-port) N     
    
  • The requested domains enclosed in one string within double quoters and separated by spaces, like "test1.acme.com test2.acme.com test3.acme.com"
     -domains VAL
    
  • The registration contact information, like admin@acme.com. Let's Encrypt doesn't support API to add new contact after * the ACME account has been registered.
     -contact VAL
    

Generating SSL Certificates for new FWD Accounts

When using FWD's Cryptography Tool, you can generate self-signed certificates only for the newly added accounts. Configure the FWD Server's directory with the new accounts, and use these arguments:

-dir [path-to-directory.xml] --reuse-passwords yes --reuse-ca yes --private-key-password [root-ca-private-key]  --build-alias-certs [account-alias]

The [account-alias] is the value you set at the FWD account's alias attribute, in the directory (IMPORTANT: these aliases must be unique across all FWD accounts, otherwise FWD will not be able to uniquely identify the FWD account for a SSL connection).

Exporting Certificates from the Directory

When the Cryptography Tool is used to automatically generate and import certificates into the directory, it is sometimes necessary to obtain the certificate/private-key for a specific alias. This can be needed for calling web services or running batch processes.

There is a tool to export the certificate/private-key for a certain alias, which can receive the arguments <alias> <store-password> <keyentry-password> and the result will be placed in a key-store where the caller has control over the passwords set for the store.

This tool only exists starting in FWD v4.

Syntax:

java -classpath /path/to/p2j.jar com.goldencode.p2j.util.ExportCert [<config.xml> { <password> | - } ] <alias> <store-password> <keyentry-password>

where: * [<config.xml> { <password> | - } ] is optional and represents the path to a server config file, and its encryption password (or - if is not encrypted). If is not specified, it defaults to standard_server.xml. * <alias> represents the alias of a certificate from the directory targeted by the server configuration. * <store-password> represents the password to validate the contents of the key store. * <keyentry-password> represents the password to encrypt the private key in the store.

<store-password> and <keyentry-password> are not related to the ones generated by the Cryptography Tool (although they can be the same, there are no restrictions).

For this tool to work properly, the certificate, its private key and its encryption password (as generated by SSLCertGenUtil) must all exist in the directory.xml.


© 2004-2021 Golden Code Development Corporation. ALL RIGHTS RESERVED.