3
$\begingroup$

Encrypt a single file, chunk-by-chunk, each chunk using different key.
I am a security newbie (only took 2 security courses before)
But currently I am using this encryption method for my Android application, which perform client-side encryption and upload each encrypted chunk into different cloud storage (Dropbox, Box, Google Drive, SkyDrive) {The app is not yet published in google market, and is planned for publish after it is stable}
But somehow I think it seems like it is doing extra works without adding extra level of security.

Steps as below:

  1. Using PBKDF2, I derive 1 master key (Km) and 1 database key (Kd) from two passwords provided by user
  2. Then I further derive multiple partial keys (Ki...Kn) from (Km) using PBKDF2 with random salts. The salts (Si...Sn) are stored in a database encrypted with (Kd)
  3. Then I split a file into multiple chunks (4MB), and encrypt each chunk with different partial key (Ki...Kn)
  4. The information of which salt is associated with which chunk is stored as file metadata in database. (the database is stored in cloud storage too)
  5. The same steps goes for decryption, in reverse way (take 2 passwords from user, derive Km and Kd, decrypt database, retrieve salts from database, derive Ki...Kn from Km + salts, decrypt each file chunk, merge each chunk back to original file.

Initialization vector (iv) is also used when initialize the cipher, but I don't mess anything with it. I follow the original method and I just append it infront of my file chunk as plain text.

As far as I understand the usage of Salt is we don't need to keep it secret. As it simply makes brute force attack slower.
But in my case, I am keeping the salt secret (some people call it pepper, or shared secret)

My main questions are:
1) Is my design flawed?
2) If it is not flawed, does it provide extra security? instead of just slowing down brute force. Or is my design totally pointless and extra?
3) Any else comments are welcomed.

$\endgroup$
  • $\begingroup$ What is the reasoning for distributing a file on multiple cloud services? So is it lost if any of them fails? $\endgroup$ – Paŭlo Ebermann May 2 '13 at 19:40
  • $\begingroup$ @PaŭloEbermann for improved bandwidth utilization, bypassing limited upload size, and some minor security improvement. Yes, if any of them fails, data cannot be reconstructed. But I added erasure coding(RAID5) instead of simple data striping(RAID0), so it protects from several providers fails, depending on my scheme (3+1) (4+2) etc $\endgroup$ – tcboy88 May 5 '13 at 13:37
5
$\begingroup$

Step 1: good job, this is the right way. You can also use bcrypt or scrypt for extra resistance. Make sure you have chosen sufficiently strong parameters, that is, 64-bit salt and 10000 rounds absolute minimum.

Step 2: no! once you have a strong derived master key, you don't need to apply PBKDF2 on any keys derived from this master key. You are just wasting time and effort and it doesn't scale at all. Use HMAC with a random nonce and keyed with the master key.

Step 3: Why not just encrypt the whole file with a single (derived) key? Why would you want to split the file into chunks? If you do have a good reason, ignore this.

Step 4: I.. suppose.

Step 5: Yeah.


Is my design flawed? Well I won't lie to you, it is a bit weird. You don't need to split the file into chunks if you just want to encrypt it. You are making it needlessly complex. Unless you have good reason. Now the real problem is you have no mechanism in place for integrity checking and authentication. That is BAD.

Or is my design totally pointless and extra? Frankly, yes, it is.

Any else comments are welcomed. Do not design your own real world cryptosystem. Either you do it the simple way and have someone competent (or better yet, multiple) look over it before deploying it, or don't do it at all. Mindlessly throwing cryptography at a problem isn't the right approach.

The problem I have with this question is that you have no clear goal in mind. What are you protecting against? What is your threat model? Where is the database stored? Who or what will access it? etc..

Without knowing this, "extra security" doesn't mean anything. More secure than what, against what?


TL;DR: design is flawed and over-engineered, designer should not be designing cryptosystems for real world use (though it's fine to experiment, of course). Best use an existing file encryption scheme (there ought to be millions for Android, but OpenSSL will do fine) and store metadata in a secure database.

$\endgroup$
  • 1
    $\begingroup$ @tcboy88 You don't need new keys for every single chunk. You can encrypt with a parallelisable algorithm (say, CTR) with the right IV and with the same key and then simply send that chunk. You'll be able to decrypt it when you get it back (even without other chunks, yes). But you need to store a MAC to make sure the chunk makes it back from the cloud intact (has not been modified by an attacker or simply damaged somehow) $\endgroup$ – Thomas May 2 '13 at 10:47
  • 1
    $\begingroup$ @tcboy88 The passwords are fine, it makes sense to separate passwords like this. However, for the integrity check, CRC32 is not good enough, and SHA1-256 (btw, that's SHA2, SHA1 is 160 bits only) is inadequate because you are letting the attacker find collisions which will break your integrity scheme. Better HMAC it with the cloud storage's key. $\endgroup$ – Thomas May 2 '13 at 10:50
  • 1
    $\begingroup$ @tcboy88 Yes, the multi-keys idea is not really good. Having that many keys to go around is a huge gaping hole just waiting to be exploited. Just use a single key, use an encryption method which allows for parallel encryption (btw, I doubt even single-threaded encryption is slower than uploading your stuff to the cloud...) and use different IV's for each file. Much safer and easier than having to manage hundreds of keys. $\endgroup$ – Thomas May 2 '13 at 10:51
  • 1
    $\begingroup$ You should mention this is for a school project in the original question. I was led to believe this was for a real application (you said "Android application"). $\endgroup$ – Thomas May 2 '13 at 10:52
  • 1
    $\begingroup$ Alternatively to CTR, you can simply use GCM mode which has authentication built-in, not requiring a separate HMAC. You can always send distinct blocks to multiple cloud services for storage, but it does require all of the blocks to decrypt any of them. $\endgroup$ – Stephen Touset May 2 '13 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.