SolFS, having convenient file management features and built-in encryption, is often used for Digital Rights Management (DRM). In other words, developers use SolFS to secure information and to prevent unauthorized access to this information. Unauthorized can mean access by third-parties, but also by the user himself. It's a common task when 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 use is that reliable DRM is a hardly achieveable goal. You can implement it, but to implement it right you need to employ more than just a library (eg. SolFS).
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 attack on the encrypted data (when you have it) can be very time consuming either. With SolFS the keyhole is available by default. The key (password) will protect your data from the average John Doe, but not from the experienced hacker.
Protecting information from copying
First level of security is obfuscation of the file format. When the experienced hacker sees the storage, he can rather easily find out that it's SolFS. The hacker can take SolFS Explorer and attempt to open the storage. He will find out that this is SolFS Storage. To avoid this, you can apply some permutations on the storage pages. When SolFS is used in callback mode, it calls the functions, provided by your application, to read and write the pages from/to the storage. You can write and read the pages as is, but you can also change them. Changes can be as simple as XOR'ing the bytes with some constant, or you can even employ some encryption algorithm. Callback mode is decribed in the corresponding article.
The next step is protecting the key. To use built-in encryption features of SolFS you provide a password (passphrase) which SolFS uses to encrypt the files (when you encrypt the files one by one) or the whole storage (when whole-storage encryption is used). And this is a good vector for attack carried by the experienced hacker. No matter how you or SolFS secure the password, there's a place where this password is in clear text - it's where the password is transferred from your code to SolFS code. Can we pass the password not in 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. There are two approaches to secure the key. Both of them require custom encryption, which is possible using encryption and hashing callbacks of SolFS. First approach relies on code obfuscation. Second approach provides almost 100% protection but requires hardware support. The differences between the approaches will be described below.
To get custom encryption you need to take several steps:
- Set encryption mode for the storage or the files that you want to encrypt to Custom.
- Implement handlers for OnDataEncrypt, OnDataDecrypt callbacks. They will be used for encryption of the data.
- Implement handlers for OnHashValidate and OnHashCalculate callbacks. They will be used for hash calculation.
Now it's time for encryption and 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. Obfuscation of the executable code is done using special tools which are not mentioned here intentionally. The goal of code obfuscation is to make it harder if not impossible even for the hacker to find out the password and permutation algorithm used.
The second approach requires that you use cryptographic hardware (USB cryptotokens or smart cards). The symmetric key, used for encryption/decryption of the disk data, is stored on hardware. Cryptographic hardware supports both storage of the secret keys and 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 passphrase. And you can re-encrypt the data using other key if needed: most hardware lets you generate a symmetric key and store it in the device.
This approach has several disadvantages:
- The cryptographic hardware is quite slow when performing encryption/decryption operations. This will slow down disk operations significantly.
- Hardware costs money (min. 50 USD for a USB cryptotoken at the moment of writing) and it needs physical shipping to your clients.
- You get very high level of protection for your data.
- 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 on other systems.
Controlling the user access
User rights control is possible when your data can't be easily extracted and copied to the external media for unprotected access. The measures to prevent this were discussed above. Here we will discuss several possible ways to control access to information by several users.
When you ship some data, you might want to make this information available to certain list of users / devices while preventing others from using your application and accessing the data. This can be done using PKI.
PKI stands for Public Key Infrastructure, the set of standards and protocols that let you use asymmetric cryptography (also called public key cryptography) to sign and encrypt the data in order to prove authenticity of the data and to secure the data from unauthorized access.
In our scenario we will encrypt the encrypted key used to encrypt the key used to access SolFS storage. Is this too complicated? This is just the beginning ;-). SolFS data is encrypted with the key, which we will call SolFSKey. 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 acess to this key.
First case is when we don't have hardare in our scheme. In this case you need to encrypt SolFS Key using some random key (we'll name it RKey). You encrypt 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). This block of data will be decrypted by your application by applying user's private key. The decrypted RKey will be used to decrypt SolFSKey in your application. No need to say, that RKey decryption and SolFSKey decryption procedures must be obfuscated.
If we have the hardware, the scheme is slightly different. The cryptocard or USB token can be stolen. They are usually protected using the PIN (password), but as it happens with any password known to the user, they can be obtained relatively easily. So we will need to remove the human from the equation. You need to assign unique cryptographically strong PIN to each token or smartcard that you distribute (and which contain SolFSKey). 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). This block of data will be decrypted by your application by applying user's private key. The decrypted PIN will be used to access the hardware using PKCS#11 interface which lets you provide the PIN programmatically (Windows CryptoAPI doesn't let you pass the PIN in code). No need to say, that PIN decryption decryption procedures must be obfuscated. Now the attacker would need to steal the hardware and the private key in order to just get access to any of your data, stored in SolFS storage. Since the user doesn't have a PIN for the hardware, he can't use this hardware to store his 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 are not the only information that you can store in 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 permission checking code must be protected in some way.
The ideas discussed above are not the only possible ways to secure your information. You are welcome to improve the offered schemes and create your own schemes if needed. It's very hard to secure information from the curious mind that has access to this information (even in encrypted form), but the most creative you are, the stronger protection is. Just note, that cryptography itself must be implemented by professionals.
To implement the whole scheme correctly you need certain cryptographic library. EldoS Corporation offers SecureBlackbox® for Developers, the product that will let you use both symmetric and PKI security with SolFS.