Question

I implemented a crypto format (in the form of a MultiCipherOutputStream and a MultiCipherInputStream) that supports nesting multiple cipher streams into one another. The goal was to produce a flexible crypto file format that will satisfy even the most paranoid users. While I believe I have gathered quite a bit of knowledge about how to implement something like this, I am not an in-depth crypto expert. Background: The crypto format is for Syncany, a use-any-storage Dropbox-like file sync tool.

So my questions are:

  • Is the concept of this crypto format cryptographically sound?
  • Are any of my assumptions and design concepts wrong or questionable?
  • Is it implemented correctly?

Here is a description for the format:

Length       HMAC'd           Description
----------------------------------------------
04           no               "Sy" 0x02 0x05 (magic bytes, 4 bytes)
01           no               Version (1 byte)
12           no               Header HMAC salt            
01           yes (in header)  Cipher count (=n, 1 byte)

repeat n times:
  01         yes (in header)  Cipher spec ID (1 byte)
  12         yes (in header)  Salt for cipher i (12 bytes)
  (dyn.)     yes (in header)  IV for cipher i (cipher specific length, 0..x)    

32           no               Header HMAC (32 bytes, for "HmacSHA256")
(dyn.)       yes (in mode)    Ciphertext (HMAC'd by mode, e.g. GCM)

General design concepts and assumptions:

  • Assumption: A single password is shared among all users
  • Input parameters: Password string, list of cipher specs (e.g. AES/GCM/NoPadding, 128 bit)
  • The password is used to derive one symmetric key per cipher using PBKDF2 (12 byte salt, 1k rounds)
  • The symmetric key(s) are used to encrypt files; it is reused in max. 100 files (~ 200 MB)
  • Cipher algorithms are configurable, but not every cipher is allowed: only AES and Twofish (128/256 bit), only authenticated modes (as of now only GCM; no ECB, CBC, etc.)
  • Ciphers are initialized with a random initialization vector (IV), IVs are never re-used
  • Multiple cipher algorithms can be nested/chained (1-n ciphers), e.g. AES-128 and Twofish-256
  • Cipher configurations, IVs and salts are authenticated with an HMAC (SHA256)

Source:

Était-ce utile?

La solution

Your scheme is not very safe regarding key management, as EJP has already stipulated. The common way to do this is using asymmetric keys, e.g. the PGP key distribution scheme. Currently only one person has to leak the password to make this scheme insecure, and nobody will know who is the culprit.

Furthermore, the same password is used to derive the keys. Now I presume one of these keys is used to calculate the HMAC over the header. So that means that if a dictionary or brute force attack is feasible on the password, that the result can be checked against the HMAC over the header. Once the password is found, then the rest of the keys can be derived from it.

So although you have muliple layers of encryption, you do not have multiple layers within your key/password management scheme. Attacks will likely only focus on your key management scheme, making your the additional rounds of encryption redundant. You would actually already be a bit more secure to use a PBKDF with larger salt and iteration count initially, and then derive the keys using a KBKDF on the result of the PBKDF. But even that won't hide the issues with key management.

So no, this scheme is not particularly secure.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top