Using an HSM with confidential identities

In Corda, all nodes are associated with a public key. However, when additional privacy is required, nodes can use confidential identities. A confidential identity is a new key pair, referred to as a confidential identity key, that can be communicated to other specific nodes, which then associate the new key pair with the node that generated them.

This system allows the confidential identity keys to be used to sign transactions, without the wider network being able to associate the key pair with the signing node. Confidential identity keys can be used either by using the KeyManagementService APIs, where a CorDapp generates a fresh key pair, and communicates it to other nodes; or with the SwapIdentitiesFlow and IdentitySyncFlow.

By using an HSM, the confidential identity keys can be stored in the node database in an encrypted form. There are two supported modes for combining HSMs and confidential identities on Corda Enterprise; wrapped and degraded wrapped. Both of these modes are more secure than using confidential identities without an HSM.

The wrapped mode is the most secure, but requires specific APIs from the HSM, and not all HSMs are supported. The wrapped mode functions as detailed below:

  • The node generates a symmetric AES key inside the HSM. This key is known as the wrapping key.
  • When a confidential identity key is required, it is generated by the HSM and encrypted using the private wrapping key. The confidential identity key pair is then returned to the node as a public key and an encrypted private key.
  • The node stores the public and encrypted private key.
  • When the node needs to use the confidential identity key to sign data, the node provides the encrypted private key to the HSM, the HSM decrypts the key using the wrapping key, signs the data, and returns the signed data to the node.

This method prevents the node from having access to the unencrypted private key at any point in the key creation or data signing process.

The degraded wrapped mode is slightly less secure than the wrapped mode, but can be supported by a wider variety of HSMs. The degraded wrapped mode functions as detailed below:

  • The node generates the symmetric AES wrapping key inside the HSM.
  • When a confidential identity key is required, the node generates the key pair in local memory, which is then sent to the HSM for encryption.
  • The HSM encrypts the confidential identity key with the wrapping key, and returns the encrypted key to the node.
  • When the node needs to use the confidential identity key to sign data, the HSM decrypts the private key, which is passed back unencrypted and used by the node to sign the data in memory.

The degraded wrapped mode is considered less secure than the wrapped mode, as the private key material is exposed to the node’s memory at two points:

  • The confidential identity key is created in the node’s memory before it is encrypted.
  • Data signing takes place in the node’s memory using the unencrypted private key, rather than inside the HSM.

Confidential identities can be used with a keystore in the node filesystem. The filesystem keystore takes the role of the HSM, however, the filesystem keystore is only compatible with the degraded wrapped mode.

Using an HSM with confidential identities is not enabled by default. To enable this, the node configuration file must include the freshIdentitiesConfiguration field.

The freshIdentitiesConfiguration field contains the following attributes:

AttributeTypeRequiredDescription
modeStringYesDefines the mode of operation, valid values are: WRAPPED or DEGRADED_WRAPPED.
masterKeyAliasStringNoDefines an alias for the wrapping key. The default value is wrapping-key-alias.
cryptoServiceConfigurationN/AYesContains the cryptoServiceName and cryptoServiceConf attributes.
cryptoServiceNameStringYesDefines the type of HSM. Valid values can be found in the HSM documentation.
cryptoServiceConfStringYesDefines a path to the HSM configuration file to use, for details, see the HSM documentation.

A completed configuration file might appear as follows:

freshIdentitiesConfiguration: {
    mode: "DEGRADED_WRAPPED",
    cryptoServiceConfiguration: {
        cryptoServiceName: "BC_SIMPLE"
    },
    masterKeyAlias: "master-key",
}

The following table contains the current support and the associated configuration values:

Master key storagecryptoServiceNamecryptoServiceConfmode
file-based keystoreBC_SIMPLEnot usedDEGRADED_WRAPPED
Securosys PrimusX HSMPRIMUS_Xpath to the PrimusX configuration fileWRAPPED
AWS CloudHSMAWS_CLOUDpath to the AWS CloudHSM configuration fileWRAPPED
nCipherN_SHIELDpath to nshield.confNATIVE
FuturexFUTUREXpath tofuturex.confWRAPPED
Azure Key Vaultpath to AZURE_KEY_VAULTaz_keyvault.confNATIVE
  • For Securosys’ PrimusX HSM, this feature has been tested with an HSM running firmware version 2.7.4 and the version 1.8.2 of the PrimusX JCA provider.
  • The wrapping key is generated during node registration. So, if you want to upgrade to this secure mode of using confidential identities after having used the previous one, you will have to re-run the node registration process, which will skip the steps that have been executed already and will just generate the wrapping key.
  • The HSM needs to be configured appropriately to allow import and export operations for keys. Ideally, a separate partition in the HSM can be used for confidential identities to follow the principle of least privilege for any other partitions. Note that Corda still ensures that only the wrapped keys corresponding to confidential identities are allowed to be exported and only in wrapped form.
  • Specifically for PrimusX HSM, you will also need to enable the JCE API for wrapping (jce_process.active set to enabled) and ideally disable key invalidation (invalidate_keys set to disabled), so that ephemeral keys do not continue to consume memory after being used and explicitly cleaned up.

Configuration file example:

freshIdentitiesConfiguration {
    mode="WRAPPED"
    cryptoServiceConfiguration {
       cryptoServiceName="AWS_CLOUD"
       cryptoServiceConf="aws_cloud.conf"
    }
    masterKeyAlias="master-key"
}

The following parameters are used for confidential identities on AWS CloudHSM:

  • AES Key Wrap Algorithm (RFC 3394) with PKCS#5 padding
  • Persistent, non-extractable 256-bit AES key as a wrapping key (KEK)
  • Non-persistent (valid for the current session only), extractable EC secp256r1 key pair as an ephemeral key

To use confidential identities with an nCipher HSM, the following configuration block must be present in the node.conf file:

freshIdentitiesConfiguration: {
    mode: "NATIVE",
    cryptoServiceConfiguration: {
            cryptoServiceName: "N_SHIELD"
            cryptoServiceConf: "nshield.conf"
            cryptoServiceTimeout: 10000
    },
}

The nCipher HSM configuration file must contain the following configuration:

keyStore: "certificates/keystore.nshield"
password: "my-password

To use confidential identities with a Futurex HSM, the following configuration block must be present in the node.conf file:

freshIdentitiesConfiguration: {
    mode: "WRAPPED",
    cryptoServiceConfiguration: {
        cryptoServiceName: "FUTUREX",
        cryptoServiceConf: "futurex.conf"
    },
    masterKeyAlias: "ci-master-key-1"
}

The Futurex HSM configuration file must contain the following configuration:

credentials: 123456

To use an Azure Key Vault HSM, the following configuration block must be present in the node.conf file:

freshIdentitiesConfiguration: {
    mode: "NATIVE",
    cryptoServiceConfiguration: {
          cryptoServiceName: "AZURE_KEY_VAULT"
          cryptoServiceConf: "az_keyvault.conf"
          cryptoServiceTimeout: 10000
    },
}

The Azure Key Vault configuration file must contain the following configuration:

path: keyvault_login.p12
tenantId: "my-alias"
password: "my-password"
keyVaultURL: "[https:/](https:/)/<mykeyvault>.vault.azure.net/"
clientId: "a3d72387-egfa-4bc2-9cba-b0b27c63540e"
protection: "SOFTWARE"

Was this page helpful?

Thanks for your feedback!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.

We're sorry this page wasn't helpful. Let us know how we can make it better!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Create an issue

Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.