Digital Rights Management (DRM) with CBFS Storage

CBFS Storage, having convenient file management features and built-in encryption, is often used for Digital Rights Management (DRM). In other words, developers use CBFS Storage to secure information and to prevent unauthorized access to this information. "Unauthorized" can mean access by third parties, but also by the users themselves. It is a common scenario where the user may access the data only via the application interface, but may not export this information to external media, both electronic and physical (paper, etc.).

The problem with such a scenario is that reliable DRM is hardly an achievable goal with a single library (for example, CBFS Storage). To implement a solution, you need to employ more than just a library (for example CBFS Storage).

To get access to the protected entity, one would need to have the key and the keyhole. In other words, knowing the key won't help if you don't know where and how to use it. And brute force attacks on the encrypted data (when you have it) can be very time consuming. With CBFS Storage, the keyhole is available by default. The key (password) will protect your data from the average John Doe, but not from an experienced hacker.

Protecting Information from Copying

The first level of security is the obfuscation of the file format. When the experienced hacker sees the storage, he or she can easily discover that it's CBFS Storage. The hacker can take CBFS Storage Explorer and attempt to open the storage. He or she will discover that this is CBFS Storage. To avoid this, you can apply some permutations on the storage pages. When CBFS Storage is used in callback mode, it calls the functions provided by your application to read and write the pages to and from the storage. You can write and read the pages as is, but you can also change them. Changes can be as simple as XORing the bytes with some constant; you can also employ an encryption algorithm. Callback mode is described in the corresponding article.

The next step is to protect the key. To use the built-in encryption features of CBFS Storage, you provide a password (pass phrase), which CBFS Storage uses to encrypt the files (when you encrypt the files one by one) or the whole storage (when whole-storage encryption is used). This is an attack vector for experienced hackers. No matter how you or CBFS Storage secure the password, there's a place where this password is in clear text - where the password is transferred from your code to CBFS Storage code. Is it possible to transfer the password without using clear text? Of course, but, again, there will be some place where it will appear in clear text - either in your application or in the library.

The encryption and hashing callbacks of CBFS Storage enable you to use custom encryption to protect the key. The following sections describe two encryption approaches: The first approach relies on code obfuscation. The second approach provides almost 100% protection but requires hardware support. The differences between the approaches are described below.

Configuring Custom Encryption

Follow the steps below to configure CBFS Storage to use a custom encryption scheme:

  1. Set the encryption mode for the storage or the files that you want to encrypt to Custom.
  2. Implement handlers for the OnDataEncrypt and OnDataDecrypt callbacks. They will be used for the data encryption.
  3. Implement handlers for the OnHashValidate and OnHashCalculate callbacks. They will be used for the hash calculation.
  4. Specify the encryption and the password.
With the first approach, the idea is that you construct the obfuscated encryption key and perform encryption and decryption in your code, and this code is obfuscated to hide the key and data permutations. The obfuscation of the executable code is done using special tools, which are not mentioned here intentionally. The goal of obfuscating the code is to make it hard, if not impossible, for hackers to find out the password and the permuted algorithm used.

The second approach requires that you use cryptographic hardware (USB crypto tokens or smart cards). The symmetric key, used for the encryption / decryption of the disk data, is stored in the hardware. Cryptographic hardware supports both the storage of the secret keys and the cryptographic operations (encryption / decryption) using this key. The secret key doesn't (and can't) leave the token, so the hacker won't be able to get the pass phrase. You can re-encrypt the data using another key if needed: most hardware lets you generate a symmetric key and store it in the device.

This approach has several disadvantages:

  1. The cryptographic hardware is quite slow when performing the encryption / decryption operations. This will slow down the disk operations significantly.
  2. Hardware costs money (a minimum of $50 USD for a USB crypto token at the moment of writing) and it needs to be physically shipped to your clients.

The advantages are also significant:

  1. You get a very high level of protection for your data.
  2. You get an additional tool for license control for your data or software. It's not possible to install and use unauthorized copies of your software or export the data to use it on other systems.

Controlling User Access

User rights control is possible when your data can't be easily extracted and copied to external media for unprotected access. Below, we discuss several ways to control access to information by several users.

When you ship some data, it may be in your best interest to make this information available to a select list of users (or devices), while simultaneously preventing others from using your application and accessing the data. This can be accomplished using PKI.

PKI stands for public key infrastructure, the set of standards and protocols that enable you to use asymmetric cryptography (also called public key cryptography) to sign and encrypt data in order to prove its authenticity and to secure the data from unauthorized access.

In our scenario, there are several layers of encryption: We will encrypt the encrypted key used to encrypt the key used to access CBFS Storage. CBFS Storage data is encrypted with a key that we will call the CBFS Storage Key. As discussed above, we can either keep it in cryptographic hardware or keep it hidden in our code or data. Now, we need to prevent access to this key.

When you are not using cryptographic hardware, you need to encrypt the CBFS Storage Key using some random key (we'll name it RKey). You encrypt the RKey using the public keys that belong to the authorized users and give the encrypted RKey to the users as blocks of data in a file. The blocks of data will be decrypted by your application by applying the user's private key. The decrypted RKey will be used to decrypt the CBFS Storage Key in your application. Te RKey decryption and CBFS Storage Key decryption procedures must be obfuscated.

If you are using cryptographic hardware, the scheme is slightly different. The crypto card or USB token can be stolen. These are usually protected using a PIN (password), but as it happens with any password known to the user, the PIN can be obtained relatively easily. So, we will need to remove the human from the equation. You need to assign a unique cryptographically strong PIN to each token or smart card that you distribute (and which contains the CBFS Storage Key). You encrypt the PIN using the public keys that belong to the authorized users and give the encrypted PIN to the users as blocks of data in a file. The blocks of data will be decrypted by your application by applying the user's private key. The decrypted PIN will be used to access the hardware using the PKCS#11 interface, which lets you provide the PIN programmatically (the Windows CryptoAPI doesn't let you pass the PIN in code). The PIN decryption procedure must be obfuscated. Now, the attacker would need to steal the hardware and the private key in order to get access to any of your data stored in CBFS Storage. Since the user doesn't have a PIN for the hardware, he or she can't use this hardware to store his or her private key, and the risk of stealing both pieces of the secret is reduced this way. Only the legitimate users of your application will be able to use it.

Both of the above schemes have one more benefit besides protecting the access key. The encrypted RKey or PIN is not the only information that you can store in an encrypted data block. You can add any access control information that you need there. For example, you can specify that the owner of the private key may read the text documents but may not alter them. Of course, these permissions will be checked in your application and the permission-checking code must be protected in some way.


The approaches discussed are not the only possible ways to secure your information. Using a cryptographic library you can create your own schemes if needed. SecureBlackbox® is a professionally developed library that enables you to use both symmetric and PKI security with CBFS Storage.

Ready to get started?

Learn more about Callback Technologies or download a free trial.

Download Now