Key Handler Package

The Key Handler Package provides interfaces and handlers for managing public/private key pairs used for sealing and unsealing secure envelopes (often referred to as sealing or signing keys). TRISA nodes must handle keys in a variety of formats, such as x.509 certificates on disk or marshaled data when sending keys in TRISA key exchanges. The key management package makes PKS simpler by standardizing how keys (both private and public keys) are managed, serialized, and stored.

Godoc Package Reference: github.com/trisacrypto/trisa/pkg/trisa/keys

TRISA strongly recommends that sealing/unsealing keys be distinct from identity certificates for improved security and to support differing retirement criteria. Some organizations may choose to use unique sealing/unsealing keys with each unique counterparty. Others may choose to issue new sealing/unsealing keys every month, deleting keys after the compliance window is over to “erase” private information (which cannot be decrypted without the keys). Either way, when multiple keys are involved, some key management system is needed. The handlers in this package ensure that keys are managed consistently for long-running systems.

Note

The key handler package is not intended to help or handle the symmetric keys that are used to encrypt payloads. For more information on symmetric cryptography, please see the github.com/trisacrypto/trisa/pkg/trisa/crypto package.

Key Interface

The Key interface is a generic interface to either a private key pair or to a public key that has been shared in a TRISA key-exchange. The primary use of this top-level interface is serializing and deserializing keys with the marshaler interface and creating a unified mechanism to manage keys on disk.

type Key interface {
    PublicKey
    PrivateKey
    KeyMarshaler

    IsPrivate() bool
}

The PublicKey interface provides access and management of a public key, either as part of a key pair or a stand-alone public key. Critically, this interface allows you to identify the key type using a signature-based identifier of the public key for the key management. This identifier should be added to secure envelopes to ensure the envelope cryptography can be matched with the correct keys.

Public keys are used to seal envelopes, typically using the RSA public key algorithm. When part of a private key pair, public keys should be serialized to send to counterparties during key exchange into a trisa.api.v1beta.SigningKey message. The SigningKey message provides metadata for decoding a PEM encoded PKIX public key for RSA encryption and transaction signing.

type PublicKey interface {
    KeyIdentifier

    SealingKey() (interface{}, error)

    Proto() (*api.SigningKey, error)
}

The PrivateKey interface provides access to the private key object that can be used to unseal an envelope, typically an RSA Private Key. While all keys managed by a TRISA node have a public key component, not all keys managed by a TRISA node will have the private component. Private key pairs belong to the node itself and TRISA recommends slightly different key management for these keys, ensuring robustness and security of storage, using a key manager such as Vault, KMS, Kubernetes Secrets, etc.

type PrivateKey interface {
    UnsealingKey() (interface{}, error)
}

The KeyMarshaler interface provides mechanisms for marshaling and unmarshaling keys either from disk or during key exchange. Key storage and management is discussed further in the next section.

type KeyMarshaler interface {
    Marshal() ([]byte, error)
    Unmarshal(data []byte) error
}

Key Management

Currently, the keys package wraps two types of objects:

  1. An x.509 Certificate either as a key pair or a stand alone certificate. These types of certificates and private keys are what the TRISA GDS issues to users.
  2. A trisa.api.v1beta1.SigningKey protocol buffer message sent during a key exchange and containing only public key information.

Keys can be instantiated from objects using one of the following methods:

Alternatively, they can be parsed from raw data using the ParseKeyExchangedata function, which tries a variety of parsing techniques from PEM encoded data to raw certificate material, to protocol buffer unmarshaling.

When storing private key pairs on disk, TRISA recommends using the Marshal and Unmarshal functions of the Certificate object, which creates PEM encoded keys. Private key pairs should be stored securely, using a dedicated key management system or encrypted disk.

To handle PKCS12 encrypted certificates sent from the GDS via email, use the TRISA trust Serializer to decrypt a trust Provider which can then be used to collect the Certificate object. At this point, the certificates are decrypted and can be marshaled and unmarshaled into secure storage.

Public Exchange keys received from counterparties should be cached in memory for a short duration, and key exchanges should be conducted routinely to ensure the correct keys are used. TRISA recommends caching public keys from counterparties for at most 1 hour or for the duration of a TransferStream RPC. When creating secure envelopes in batch, if the counterparty is unreachable for a key exchange, you may request the sealing certificate of the counterparty from the GDS using the Lookup RPC.