IBM Cloud Docs
Using Hyper Protect Crypto Services PKCS #11 for IBM Db2 native encryption

Using Hyper Protect Crypto Services PKCS #11 for IBM Db2 native encryption

IBM Db2® native encryption protects key database files and database backup images from inappropriate access while they are stored on external storage media. The database system automatically encrypts and decrypts data when it is used by authorized users and applications. Typically, database users do not need to be aware of native encryption and database client applications do not need to be adapted specifically.

Db2 native encryption uses a two-tiered key hierarchy: Data is encrypted with a data encryption key (DEK). The DEK is encrypted with a master key and is stored in encrypted form with the database or the backup image. A unique DEK is generated by Db2 for each encrypted database and for each encrypted backup.

A master key is used to encrypt a DEK. Each encrypted database is associated with one master key at one time.

One important question when you plan for Db2 native encryption is where you keep the master key and how you secure it.

Objectives

This tutorial shows how you can keep complete and exclusive control of your master keys by storing them in IBM Cloud® Hyper Protect Crypto Services. For this purpose, you need to use the PKCS #11 integration feature of Hyper Protect Crypto Services.

With this tutorial, you are going to implement the setup that is depicted in the following illustration.

IBM Db2 default encryption with the standard PKCS #11 API
Figure 1. IBM Db2 default encryption with the standard PKCS #11 API

In this setup, Db2 is to call operations to manage the master keys on the Hyper Protect Crypto Services PKCS #11 library. The Hyper Protect Crypto Services PKCS #11 library interacts with your Hyper Protect Crypto Services instance, which provides the best of class technology for storing and managing your master keys.

Before you begin

To complete this tutorial, you need to meet the following prerequisites:

Task flow

To complete this solution, let's walk through the following steps:

  1. Initialize your Hyper Protect Crypto Services instance
  2. Set up the Hyper Protect Crypto Services PKCS #11 library
  3. Set up Db2 and configure Db2 native encryption

Initialize your Hyper Protect Crypto Services instance

  1. For this tutorial, you need to initialize a Hyper Protect Crypto Services instance first.

    Note down the ID of your Hyper Protect Crypto Services instance and the EP11 endpoint address. You need this information for the subsequent steps.

  2. Create a custom IAM role Discover HPCS. This role provides a very limited permission for discovering your Hyper Protect Crypto Services instance, which is required by the PKCS #11 library. This role does not have permissions to use, create, or manage keys or EP11 keystores.

    1. From the UI, go to Manage > Access (IAM), and select Roles, and then click Create.
    2. Enter the name Discover HPCS for your role.
    3. Enter an ID for the role. This ID is used in the CRN, which is used when you assign access by using the API. The role ID must begin with a capital letter and use alphanumeric characters only; for example, DiscoverHPCS.
    4. Optional: Enter a succinct and helpful description that helps the users who are assigning access know what level of access that the role assignment gives a user. This description also shows in the UI when a user assigns access to the service.
    5. From the list of services, select Hyper Protect Crypto Services
    6. Select Add for the hs-crypto.discovery.listservers action, and then click Create.
  3. Follow the instructions in Setting up PKCS #11 API user types to set up the service IDs and API keys for the normal user and anonymous user.

    Do not set up the SO user type that is mentioned in the instructions. Also, in contrast to the instructions, do not assign the anonymous user service ID the Key operator custom role, but assign the Discover HPCS custom role instead.

    With this setup, the anonymous user has only very limited permissions on your Hyper Protect Crypto Services instance and cannot use, create, or manage keys or EP11 keystores.

  4. Save the value of the API keys for the normal user and the anonymous user for subsequent steps.

  5. Follow the instructions to create a private EP11 keystore and note the keystore ID for subsequent steps.

Set up the Hyper Protect Crypto Services PKCS #11 library

1. Run the Db2 Community Edition container

  1. Use the following command to run the Db2 Community Edition container:

    docker run -itd --name mydb --privileged=true -p 50000:50000 -e LICENSE=accept -e DB2INST1_PASSWORD=password -e DBNAME=testdb ibmcom/db2
    
  2. Run the following command from a command line on your host system:

    docker exec -it --user root --workdir / mydb bash
    

This shell is to be used to run the commands as root for the subsequent steps.

2. Create the Hyper Protect Crypto Services PKCS #11 configuration file

Now, create a configuration file for the Hyper Protect Crypto Services PKCS #11 feature. The configuration file is named grep11client.yaml.

Adapt the following file template and name the file grep11client.yaml:

  • Replace <instance_id> with the ID of your Hyper Protect Crypto Services instance
  • Replace <EP11_endpoint_URL> and <EP11_endpoint_port_number> with the respective parameters of the EP11 endpoint address of your Hyper Protect Crypto Services instance
  • Replace <private_keystore_id> with the ID of the private keystore you created previously
  • Replace <anonymous_user_api_key> with the respective API key of the anonymous user
iamcredentialtemplate: &defaultiamcredential
          enabled: true
          endpoint: "https://iam.cloud.ibm.com"
          # The Universally Unique IDentifier (UUID) of your Hyper Protect Crypto Services instance.
          instance: "<instance_id>"

tokens:
  0:
    grep11connection:
      # The EP11 endpoint address starting from 'ep11'. For example: "ep11.us-south.hs-crypto.cloud.ibm.com"
      address: "<EP11_endpoint_URL>"
      port: "<EP11_endpoint_port_number>" # The EP11 endpoint port number
      tls:
        enabled: true # EP11 requires TLS connection.
        mutual: false
    storage:
      remotestore:
        enabled: true
    users:
       # The Security Officer (SO) user
      0: # The index of the Security Officer (SO) user MUST be 0.
        # The name for the Security Officer (SO) user. For example: "Administrator":
        name: "Administrator"
        iamauth: *defaultiamcredential
      # The normal user
      1: # The index of the normal user MUST be 1.
        # The name for the normal user. For example: "Normal user":
        name: "Normal user"
        # The 128-bit UUID of the private keystore which you created previously
        tokenspaceID: "<private_keystore_id>"
        iamauth: *defaultiamcredential
      # The anonymous user
      2: # The index of the anonymous user MUST be 2.
        # The name for the anonymous user. For example: "Anonymous":
        name: "Anonymous"
        # The public keystore will not be used with this setup.
        # Specify an arbitrary 128-bit UUID below, e.g.:
        tokenspaceID: "12345678-1234-1234-1234-1234567890AB"
        iamauth:
          <<: *defaultiamcredential
          # Provide the API key for the Anonymous user.
          apikey: "<anonymous_user_api_key>"
logging:
  # Set the logging level.
  # The supported levels, in an increasing order of verboseness: 'panic', 'fatal', 'error', 'warning'/'warn', 'info', 'debug', 'trace'. The Default value is 'warning'.
  loglevel: "info"
  logpath: "/tmp/grep11client.log" # The full path of your logging file.

3. Install the Hyper Protect Crypto Services PKCS #11 library

  1. Download the latest PKCS #11 library.

  2. Copy the previously created configuration file grep11client.yaml and the PKCS #11 library pkcs11-grep11-<platform>.so.<version> into your Db2 container.

  3. Run the following commands as root to install the Hyper Protect Crypto Services PKCS #11 library in your Db2 setup.

    mkdir /etc/ep11client
    chmod a+rx /etc/ep11client/
    cp grep11client.yaml /etc/ep11client/grep11client.yaml
    chmod a+r /etc/ep11client/grep11client.yaml
    
    mkdir -p /pkcs11
    cp pkcs11-grep11-<platform>.so.<version> /pkcs11/pkcs11-grep11.so
    chmod -R a+rwx /pkcs11
    
    touch /tmp/grep11client.log
    chmod a+rw /tmp/grep11client.log
    

Set up Db2 native encryption

Now, let's set up Db2 native encryption. To do so, make sure that you have all database administrator privileges.

  1. Create the file /pkcs11/keystore.conf with the following content:

    VERSION=1
    PRODUCT_NAME=Other
    ALLOW_KEY_INSERT_WITHOUT_KEYSTORE_BACKUP=true
    LIBRARY=/pkcs11/pkcs11-grep11.so
    SLOT_ID=0
    NEW_OBJECT_TYPE=PRIVATE
    KEYSTORE_STASH=/pkcs11/pkcs11_pw.sth
    
  2. Run the following commands as root to update ownership and permissions of file /pkcs11/keystore.conf:

    chown -R db2inst1:db2iadm1 /pkcs11/keystore.conf
    chmod ug+rw /pkcs11/keystore.conf
    
  3. To create a password stash file, run the following commands and replace <normal_user_api_key> by the API key of the normal user that you created.

    su - db2inst1
    db2credman -stash -password "<normal_user_api_key>" -to /pkcs11/pkcs11_pw.sth
    
  4. To update the Db2 configuration, run the following command as user db2inst1:

    db2 update dbm cfg using keystore_location /pkcs11/keystore.conf  keystore_type pkcs11
    
  5. To set the environment variable DB2_DEK_MAC_TYPE, run the following commands as user db2inst1 and restart DB2:

    db2 terminate
    db2stop
    export DB2_DEK_MAC_TYPE=HMAC
    db2start
    

    You need to specify the environment variable DB2_DEK_MAC_TYPE=HMAC before you start Db2. If you use Db2 on Windows, you need to set the Db2 profile variable by using the following command:

    db2set -g DB2_DEK_MAC_TYPE=HMAC
    
  6. To create an encrypted database, run the following commands:

    db2 create db cryptdb1 encrypt
    

    This command prints the following information:

    DB20000I  The CREATE DATABASE command completed successfully.
    
  7. To test the encrypted database, run the following commands:

    db2 connect to cryptdb1
    db2 "create table test (id int not null, data varchar(100))"
    db2 "insert into test values (1, 'This is a secret text')"
    db2 "select * from test"
    

    This command prints the following information:

    ID          DATA
    ----------- ----------------------------------------------------------------------------------------------------
          1 This is a secret text
    
    1 record(s) selected.
    

Next steps

Your sensitive data is now stored safely in encrypted storage. And the master key is kept in Hyper Protect Crypto Services in a highly secure and tamper-proof manner.

In this tutorial, you learned how to set up Db2 native encryption with Hyper Protect Crypto Services.