Thursday, January 22, 2015

Boss, I rotated the keys! (DB2 database encryption)

In my previous entry I wrote about how I created an encrypted database. Today, I am showing you how I rotated one of the keys used for the DB2 native encryption.
The key to security (Evan-Amos via Wikipedia)

DB2 uses a two tier approach for encrypting the data. A so-called Data Encryption Key (DEK) is the one actually taken as input for the encryption algorithm. To prevent others from accessing and seeing the DEK, a second layer is added and the so-called Master Key (MK) comes into play. The MK is used to encrypt the DEK. The encrypted DEK is stored inside the database, the MK outside of it and there are options for how to handle it. Walid has details about the encryption keys and the overall architecture in his blog.

Because the Master Key is stored outside of the database and is the one that needs to provided when starting up DB2, it is a good time to change it from time to time. Many companies actually have security policies that require periodical change of passwords. That is the moment to use the new DB2 administrative procedure ADMIN_ROTATE_MASTER_KEY. If you went with the option of DB2 generating the MK for you (I did for simplicity), then you only have to call the procedure and be done:


  Value of output parameters
  Parameter Name  : LABEL
  Parameter Value : DB2_SYSGEN_hloeser_ENC1_2015-01-22-12.01.20

  Return Status = 0

The call generates a new master key and associated label and then re-encrypts the Data Encryption Key with the new MK. If you provided a Master Key and label during the setup yourself, then you have to change the MK first and then call the procedure with the label as parameter.

Of course, if you noted down that generic label that DB2 generated for you, then you could use it as input. It would use the stored Master Key to re-encrypt the DEK. It would not change any password in that case. So be careful!

db2 "CALL SYSPROC.ADMIN_ROTATE_MASTER_KEY ('DB2_SYSGEN_hloeser_ENC1_2015-01-22-12.01.20')"

  Value of output parameters
  Parameter Name  : LABEL
  Parameter Value : DB2_SYSGEN_hloeser_ENC1_2015-01-22-12.01.20

  Return Status = 0

Tuesday, January 20, 2015

Plain and clear: Native encryption in DB2

Native encryption in DB2
Built-in data encryption is a newly available DB2 feature as of today (see this updated fixpack summary page for fixpack 5). Here is a short report on how I tried and succeeded in setting it up and encrypting a new DB2 database on my Linux box. What I did is more or less to follow the implementation guide for native database encryption. So let's see how this worked out...

To use native encryption, i.e., encryption built into DB2 you need at least DB2 V10.5 with fixpack 5. The fixpack was released last December. If you are already on that software level, installation is (almost) complete. In most cases you only have to update the environment variable with path information for executables and libraries (PATH and LD_LIBRARY_PATH on Linux/UNIX). They have to include the "gskit" (Global Security Kit) that is shipped with DB2. Details are in the implementation guide. All I did for the setup was to edit the db2profile (or db2cshrc) file that manages modifications to the shell environment.

I ran into two issues that I could resolve:
  • When trying to call gsk8ver as a small test, linker errors were reported. This was called with another, incompatible gskit installation on my machine that was showing up in the environment before the DB2 variables were set. After removing the other kit, the problem was gone.
  • Even though I have a 64 bit Linux system, I had to set the library path to both the 64 bit and 32 bit libraries.
Once calling "gsk8ver" can be called successfully the system is ready for the actual setup of database encryption. You need a keystore on your machine and tell DB2 how to find it.

[henrik@mymachine]$gsk8capicmd -keydb -create -db db2pwstore.p12 -pw Str0ngPassw0rd -strong -type pkcs12 -stash

The above command creates the mentioned keystore, a "key database", with the name "db2pwstore.p12". The option "strong" causes the tool to check that the requiremnts for a strong password are met. The "stash" tells it to create a so-called stash file which allows to automatically provide the password, e.g., when DB2 starts up.

With the password database in place, DB2 needs to know about it. Else you recieve this error:

[henrik@mymachine]$ db2 create db enc1 encrypt
SQL1728N  The command or operation failed because the keystore could not be accessed. Reason code "1".

There are two new DB2 instance variables  (dbm configuration parameters) for encryption: KEYSTORE_TYPE tells which password type is used, KEYSTORE_LOCATION provides DB2 with the path to the key database we just created. Update the instance variables:

[henrik@mymachine]$ db2 update dbm cfg using keystore_type pkcs12 keystore_location /home/hloeser/db2pwstore.p12

Thereafter be sure to restart DB2 (db2stop / db2start). And finally (see CREATE DATABASE for the new ENCRYPT option):

[henrik@mymachine]$ db2 create db enc1 encrypt
DB20000I  The CREATE DATABASE command completed successfully.

[henrik@mymachine]$ db2 connect to enc1

   Database Connection Information

 Database server        = DB2/LINUXX8664 10.5.5
 SQL authorization ID   = HLOESER
 Local database alias   = ENC1

Done. My database is encrypted. Because I am using a stash file (see above) I don't need to provide a password on startup. For environments where a higher degree of security is needed, there are other ways of providing the password. I plan to cover more details in upcoming blog posts. Today's entry should have provided you with a quick introduction into how to set up an encrypted database.