(This article was also published on the HissenIT Blog.)

Key wrapping is a simple technique in cryptography that is used in almost all common encryption technologies. Encrypted e-mail is a perfect example. No matter if you are using S/MIME and X.509 certificates or OpenPGP/GnuPG, encrypting an e-mail always uses hybrid encryption. That simply means, that not only one encryption algorithm is used but two are combined. You as the user do not realize that, everything happens under the hood. You look at the encrypted e-mail and only see your RSA key or certificate but the e-mail is encrypted using, e.g., AES.

Why is this done? The answer is quite simple. Asymmetric encryption, like RSA, is very slow in comparison to symmetric ciphers, like AES. So what happens is, an AES key (call it session key) is generated and AES is used to encrypt the e-mail. This AES key is then encrypted using RSA and is attached to the e-mail as well. An AES key is 16, 24 or 32 bytes in size, so very small in comparison to any e-mail you might be writing (maybe including attachments).

The same principal is used at HTTPS (SSL/TLS), where the user might only see the RSA certificate of the server, but under the hood symmetric ciphers are used. The same is true for SSH, SCP and others.

While in these cases the symmetric key is wrapped using an asymmetric cipher, key wrapping is also used in pure symmetric encryption scenarios. This applies to many applications using password based encryption. Let's take TrueCrypt and its derived successors as an example. Have you ever thought about why you can change your TrueCrypt password but your whole disk has not to be re-encrypted? The answer is: because of key wrapping.

Let's say you are using TrueCrypt with one symmetric cipher. TrueCrypt will generate a key for that cipher, e.g., AES. Using a secure password based key derivation algorithm, like PBKDF2 from PKCS#5, it will generate a second symmetric key from your password or passphrase. This second key is used to encrypt the first key. The first key could be called the master key or the actual encryption key because that key is used to encrypt your data. The key generated from the password is used to encrypt that master key (wrapped). When you change your password, the master key is simply re-wrapped using your new password. The new password leads to a new encryption key for the wrapping.

The same technology can be used by web applications using account passwords. CrococryptLib for instance provides a very easy way to integrate password based encryption and key wrapping. The following example could be used for Java based web applications, Java based desktop applications or Android apps. The user's password is used to easily encrypt some private data. Since key wrapping is used, the user can still change its password but decrypt the data anytime.

String password = "1stPassword";

Secret secret = new Secret(password);

//---ENCRYPTION AND KEYWRAPPING---

//Securely generate a AES-256 master key

EncryptionKey encKey = EncryptionKey.generateNewKey();

//Create a password-based key

CompactPasswordKey pwKey = CompactPasswordKey.generateKey(secret);

WrapUtil wrapper = new WrapUtil(pwKey);

byte[] pwKey_atStorage = pwKey.writeToBytes();

byte[] wrappedEncKey_atStorage = wrapper.wrapToBytes(encKey);

String message = "A text message, file, binary or stream";

String encryptedMessage = new CompactEncryption(encKey).encryptToBase64(new StringData(message));

//---DECRYPTION---

//Load the key material

pwKey = CompactPasswordKey.newInstance(secret).readFromBytes(pwKey_atStorage);

wrapper = new WrapUtil(pwKey);

encKey = wrapper.unwrapFromBytes(wrappedEncKey_atStorage);

//Perform the decryption

System.out.println("Decrypted message:" +

new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));

//---REWRAPPING A KEY AT A PASSWORD CHANGE ---

//(old and new password are required)

String newPassword = "newPassword";

CompactPasswordKey newPwKey = CompactPasswordKey.generateKey(new Secret(newPassword));

//Note: The actual encryption key remains the same, although the password was changed.

// Hence, all encrypted data can still be decrypted! This is why there is the

// master key and the key encryption key (in this case password-based).

wrappedEncKey_atStorage = wrapper.rewrapFromBytes(wrappedEncKey_atStorage, newPwKey);

pwKey_atStorage = newPwKey.writeToBytes();

//---RETRY THE DECRYPTION WITH THE REWRAPPED KEY---

//(only for demonstration)

encKey = new WrapUtil(newPwKey).unwrapFromBytes(wrappedEncKey_atStorage);

System.out.println("Decrypted message (new password): " +

new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));

You can download this running example within the CrococryptLib SDK and use it in your own application.