Broadleaf Microservices

Generating Encryption Keys for Production

Overview

We often make use of encryption keys in our services such as when signing and verifying the JWT tokens we issue or encrypting data for persistence. This allows us to be sure that the tokens were issued by one of our services and have not been manipulated by a third party. This document will be a reference on a simple way to generate keys that are compatible with our services.

Generating RSA Private and Public Key

These commands generate and use 2048-bit private keys in an unencrypted Base64 PEM PKCS#8 format using the RSA algorithm. While we are using openssl to generate these keys in this example, there are a number of utilities that can be used to generate keys, and so pick which works best for your environment.

Tip
The AuthenticationServicesImage included with starter projects contains a KeyGeneratorUtil that can be used to generate RSA (2048-bit) and AES (256-bit) keys.

First, we need to generate the private key:

openssl genpkey -algorithm RSA \
    -pkeyopt rsa_keygen_bits:2048 \
    -pkeyopt rsa_keygen_pubexp:65537 | \
  openssl pkcs8 -topk8 -nocrypt -outform pem > rsa-2048-private-key.p8

The contents of the private key should look like the following:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsRnE83rm6BJya
nTyzVqX0SG+D4zBjkyWsOmGG+CoDdgQ6Z8AaocmnjP1SbRykQsQSMf6SeW+fdpH+
ccmzuHe7pZIa2o2Mg8xbk/UszJDaPztwoQbUt/2gHi/rZP8cIVkquzhnN/yxrMls
w3cT+YkDC5xdLQLxcaSjbyzgFOCH/5IFi/3pPP205+UWNkMl9wKNp8k7aWb58nZX
A/XZtYT8ga7aAU+E0nfNoL1hGfjEwCmmKO27Ex8w0AyssM89rb4MaST4BHYg7YT1
GiSQ1ICdk0DJZ4ISFhUl3WvGEPOYUhnGIxX/jh1y8Ug/+AwbaHZDrKsh9ccncLRB
0CzJ+DcTAgMBAAECggEAApTToYvc0JK9Hfv5Kt7DgdOMCDfhQ7yytc/yIimZx49/
JLjlQgDmmqIcMZ387eEqOvOQ0vUK3SLTsTJXSWAcOy2R8OEReeeHql+fLtqp2PtV
...
-----END PRIVATE KEY-----

Note: Be sure to keep this key PRIVATE! It is a secret, and anyone with it can sign things as if they are you.

Second, we need to extract the public key from the private key we just generated:

openssl pkey -pubout -inform pem -outform pem -in rsa-2048-private-key.p8 -out rsa-2048-private-key.spki

The contents of the public key should look like the following:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArEZxPN65ugScmp08s1al
9Ehvg+MwY5MlrDphhvgqA3YEOmfAGqHJp4z9Um0cpELEEjH+knlvn3aR/nHJs7h3
u6WSGtqNjIPMW5P1LMyQ2j87cKEG1Lf9oB4v62T/HCFZKrs4Zzf8sazJbMN3E/mJ
...
-----END PUBLIC KEY-----

Using the Private and Public Keys in a Service

Now that you have generated the public and private key, you will need to make use of them in your service. This way you make use of these keys may vary by environment. If you are doing a staging or development environment, which is often the case, you may choose to copy and paste the keys into the YAML property files. If you are doing a production environment, you likely have a more sophisticated and secure system for managing secrets and providing them to the application runtimes.

If you are in a staging or development environment, here is how you might make use of those two keys for the signing of preview tokens:

broadleaf:
  sandbox:
    preview:
      encoder:
        encoded-private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsRnE83rm6BJyanTyzVqX0SG+D4zBjkyWsOmGG+CoDdgQ6Z8AaocmnjP1SbRykQsQSMf6SeW+fdpH+ccmzuHe7pZIa2o2Mg8xbk/UszJDaPztwoQbUt/2gHi/rZP8cIVkquzhnN/yxrMlsw3cT+YkDC5xdLQLxcaSjbyzgFOCH/5IFi/3pPP205+UWNkMl9wKNp8k7aWb58nZXA/XZtYT8ga7aAU+E0nfNoL1hGfjEwCmmKO27Ex8w0AyssM89rb4MaST4BHYg7YT1GiSQ1ICdk0DJZ4ISFhUl3WvGEPOYUhnGIxX/jh1y8Ug/+AwbaHZDrKsh9ccncLRB0CzJ+DcTAgMBAAECggEAApTToYvc0JK9Hfv5Kt7DgdOMCDfhQ7yytc/yIimZx49/JLjlQgDmmqIcMZ387eEqOvOQ0vUK3SLTsTJXSWAcOy2R8OEReeeHql...
      decoder:
        encoded-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArEZxPN65ugScmp08s1al9Ehvg+MwY5MlrDphhvgqA3YEOmfAGqHJp4z9Um0cpELEEjH+knlvn3aR...
Note

Notice that only the content of keys are pasted here. There is no need to include the prefix and suffix lines in the PEM key files, e.g. -----BEGIN PRIVATE KEY-----.

Now the preview token encoder and decoders have enough information to sign the JWT tokens for your service using these new keys.

Notable Private and Public Keys

As a quick reference for those looking to swap out keys for a staging environment, we provide this compiled list of the known usages of private/public keys for signing JWT tokens at this time:

Authorization Keys

The following keys are used in signing and verifying the JWT tokens issued by the Authentication Service for OAuth2 Resource Security. It should be noted these same keys are used for signing and verifying the JWT session token cookie used to establish a stateless session for users that authenticate with the Authentication Service.

  • broadleaf.auth.security.oauth2.encodedPrivateKey: Encoded RSA private key in Base64 PEM PKCS#8 format. Used for signing JWT OAuth2 access tokens issued by the Authentication Service.

  • broadleaf.auth.security.oauth2.encodedPublicKey: Encoded RSA public key in Base64 PEM format. Used for verifying JWT OAuth2 access token signatures issued by the Authentication Service and consumed in a Resource Service using OAuth2 Resource Security.

Important: If deploying Auth Service separate from a composed FlexPackage containing the full commerce suite, you will need to also configure the public key you defined here broadleaf.auth.security.oauth2.encodedPublicKey as the following broadleaf.resource.security.oauth2.encodedPublicKey (see: MicroSecurityCommon: oauth2-resource-security-defaults.yml for more details)

  • broadleaf.resource.security.oauth2.encodedPublicKey needs to be defined in both Commerce Flex Package and Auth

Sandbox Preview Keys

The following keys are used in signing and verifying the JWT tokens issued by the Sandbox Service. These tokens are used as proof-of-access to preview sandbox data in a Resource Service by otherwise unauthorized API requests. The private key is to be set in the Sandbox Service, and the public key to be set within the Resource Service expected to consume the preview token.

  • broadleaf.sandbox.preview.encoder.encoded-private-key: Encoded RSA private key in Base64 PEM PKCS#8 format. Used for signing JWT preview tokens issued by the Sandbox Service.

  • broadleaf.sandbox.preview.decoder.encoded-public-key: Encoded RSA public key in Base64 PEM format. Used for verifying JWT preview token signatures issued by Sandbox Service and consumed in a Resource Service that makes use of sandbox previews.

Cart Transfer Keys

The following keys are used in signing and verifying the JWT tokens issued by the Cart Operations Service in cart transfer operations. Both keys are to be set in the Cart Operations Service.

  • broadleaf.cartoperation.transfercart.encoder.encoded-private-key: Encoded RSA private key in Base64 PEM PKCS#8 format. Used for signing cart transfer tokens issued by this service for CSRs to give to an anonymous customer to transfer a cart.

  • broadleaf.cartoperation.transfercart.decoder.encoded-public-key: Encoded RSA public key in Base64 PEM format. Used for verifying transfer cart token signatures when transferring a cart to an anonymous customer.

Database Column Encryption Keys

An additional key should be generated for use in encrypted and decrypting the client secrets for registered 3rd party Identity Providers. The KeyGeneratorUtil in the AuthenticationServicesImage included with starter projects can be used to generate a 256-bit AES key that will be printed to the console. This should be set as the value for broadleaf.auth.client.provider.encryption.encoded-key.

Tip
This tool can also be used to generate 2048-bit RSA key pairs.

Tip: Utilizing the CredentialsGeneratorUtil

Your Microservices Demo starter project ships with a test class called com.broadleafdemo.demo.CredentialsGeneratorUtil to aid in generating keys for encryption purposes in the app across different Flex Package Compositions.

This performs the same function as KeyGeneratorUtil in Auth described above, but also generates a report of all ENV properties and DB updates that likely need review.

Note
reach out to our microservices support channel if your version of the starter does not include this test class and you would like access to this example