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:
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:
Source:
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.