Cryptography/Database protection

Cryptographic protection of databases, mailinglists, memberslists.

There are many cryptographic techniques associated with databases:


 * anonymizing / aggregating / depersonalizing data, so people can get summary statistics of data without associating particular items with any one person
 * column-level encryption, with a different encryption key for each column
 * Format-preserving encryption
 * data comparison


 * transparent data encryption
 * etc.

Often databases are protected by ../full-disk encryption/, which is described in a different chapter of this book.

The shadow password file could be considered a "database" of password hash digests. Password handling is discussed in detail in another chapter of this book, ../Secure Passwords/.

data comparison
Often we want to tell someone *not* to use some piece of data. But we would rather not tell people the specific details.

For example, We often want to implement "password reset", so if someone forgets the password associated with their account on our website, they can request a password reset and then click a "password reset" link sent to their email address. We want to only allow that person to reset their own password; we certainly don't want some other person (using some other email address) to reset the password for that account. But some people say GDPR frowns on us storing everyone's email address in plaintext (in case the server backup files are stolen). One proposed approach is to store a salted and hashed email (HEM), so that when a user hits the "forgot password" button, the user can punch in an email address (which the system never stores to disk), which the system compares to the stored HEM, and only if they are the same does the system send the password reset link to that email address.

For example, we want people to know if their particular password has been revealed in a public data breach, but we don't want to make it easy for malicious people to harvest those passwords.

For example, we want to tell email marketers not to send any email to anyone on the "do not email" registry, but we don't want to make it even easier for spammers to send spam email to everyone on the "do not email" registry. One proposed approach is to avoid ever storing such email addresses directly or even in encrypted form, but instead using a one-way-hash on each submitted email address and storing only the output hash values in the database.

A variety of data masking policies have been proposed for email addresses.

Gravatar uses hashed email addresses.

Simply hashing an email address by itself generates the same hash value every time. Some people propose adding "salt" or "pepper" or both to email addresses before hashing them, so that hashed addresses in one database cannot be matched to hashed addresses (using a different salt or a different pepper or both) in some other database.

Row-level encryption
A straightforward protection scheme: One-way hash function with symmetric encryption.

1. Use a one-way hash function on the (plaintext of) the index field to create the encryption key for one row.

2. Use the encryption key for one row from step 1 as the cipher key to encrypt every data field in that row. All fields are stored encrypted, even the index field.

Symmetric encryption algorithim — the same cipher key is used to encrypt and decrypt data

Searching the database
Look for the hashed value in the index field of the database and for each matching entry decrypt the data fields using the index field as the cipher key.

Example in php code
Some very easy php pseudocode to protect your data by encrypting your databases with a one-way hash and blowfish symmetric encryption.

Using a one-way hash and blowfish symmetric encryption. 1. Insert a record of John Doe in an encrypted database. 2. Get the encrypted record of user John Doe and decrypt the data.

Insert a record of John Doe in an encrypted database.
setKey( $cipher_key );

// crypt_blowfish symmetric encryption to encrypt the data $aRecord['email']      = $bf->encrypt( $aRecord['email'] ); $aRecord['name']       = $bf->encrypt( $aRecord['name'] ); $aRecord['creditnr']   = $bf->encrypt( $aRecord['creditnr'] );

$result = sqlInsert( $aRecord ) ; ?>

Get the encrypted record of user John Doe and decrypt the data.
setKey( $cipher_key );

// crypt_blowfish symmetric encryption to ecrypt the primary key for a sql select $select_key = $bf->encrypt( $primary_key ) ;

$aRecord = sqlSelectWithPKEY( $select_key );

// crypt_blowfish symmetric encryption to decrypt the data $aRecord['email']      = $bf->decrypt( $aRecord['email'] ); $aRecord['name']       = $bf->decrypt( $aRecord['name'] ); $aRecord['creditnr']   = $bf->decrypt( $aRecord['creditnr'] ); ?>