# Hashes as mutually independent keys

For cascading encryption (ie. AES-Twofish-Serpent), the most secure implementation is with mutually independent keys. My question is if it is secure to hash the previous key for each layer of encryption. In my case, Serpent will be the innermost cipher and AES the outermost.

password = "my_hopefully_secure_password"
serpentKey = sha3_256(masterKey)
twofishKey = sha3_256(serpentKey)
aesKey = sha3_256(twofishKey)

ciphertext = aes(twofish(serpent(plaintext,serpentKey),twofishKey),aesKey)


In this case, an attacker would have to attack AES first, since it's the outer shell. Suppose that the attacker successfully found the key to AES and decrypted it. Now the attacker is left with Twofish and Serpent, but the AES key doesn't reveal anything because it's a hash of the Twofish key (hashes are one-way). If the attacker broke Twofish, they still wouldn't know Serpent's key because the Twofish key is only a hash of the Serpent key.

Is this secure?

Edit: Is this secure and does it provide 256-bit security? Would this scheme correctly implement cascading encryption and provide three layers of protection?

• If they can guess the password then everything falls apart, and people are generally not good at passwords. Commented Mar 5, 2021 at 16:32
• Yeah I know. In this case, assume that the password is strong. Commented Mar 5, 2021 at 16:33
• Why did you not this in information security? Commented Mar 5, 2021 at 22:24
• That really depends on the password strength. If the strength of the password is 256*3 then the password search is directly equal to brute-forcing ( omitting the theoretical cascading). Commented Mar 5, 2021 at 22:30
• Doesn't matter, Argon2id can only slow the attacker. You can compute this and compare the password strength to generic brute-force. Commented Mar 5, 2021 at 23:23

As Uraguan mentioned, the amount of effort required to break this scheme is proportional to the size of the keyspace. There are two limiting factors here.

One of these factors is that anybody who learns the master key can extract the others trivially. So at most, your keyspace can be 256 bits in size, since any attacker will have to at most try $$2^{256}$$ inputs to the keyspace to derive the keys. If you are using a passphrase here, the better way to do this would be to extract each key separately from Argon2, which will generally be independent. Argon2 can provide $$2^{512}$$ security at most.

The other factor here is that you're using a passphrase. If you are using a passphrase that you memorize, and not one that you've generated with a CSPRNG, then your security is limited, because people are generally bad at remembering passphrases with 256 bits of entropy. No amount of complex manipulation will change that. However, if you've picked a passphrase that is pseudorandomly generated with 256 bits of entropy, then you don't need Argon2 here because attacks on the passphrase will still require $$2^{256}$$ work and Argon2 is mostly designed to improve robustness against attacks on passwords with relatively low entropy.

If your passphrase is strong in this way, then you can use something like HKDF with HMAC-SHA-512 (or any other suitable secure hash function) and then derive keys like so:

$$mainkey = HKDF-Extract(secret, salt)$$ $$serpentkey = HKDF-Expand(mainkey, "serpent key")$$ $$twofishkey = HKDF-Expand(mainkey, "twofish key")$$ $$aeskey = HKDF-Expand(mainkey, "aes key")$$

This will provide security commensurate to the entropy in your secret up to the length of the hash function.

Having said all that, I would not generally recommend encrypting multiple times with different algorithms like this. It adds a decent amount of complexity and is not likely to appreciably improve security. The best known non-related-key attacks on AES-256 break it in $$2^{254.4}$$, which is less than four times faster than brute force and still expected to be beyond our capabilities for the foreseeable future, with the exception of quantum computers.

The security is considered to be proportional to the size of the keyspace. In your proposal, the keyspace is not increased by adding encryption layers since all keys are derived from a single password.

In the proposed case Hashes are not mutually independent keys since they are derived from a single password. If they are derived from separate password then the algorithm provides three-layered security

Based on the proposal, it can be inferred that the sequence of encryption and the key derivation has to be kept secret for improving security. This is Security through obscurity and is not considered as any stronger. Wiki

If the algorithm is not hidden then cascading encryption with keys derived from the same source is not adding any layers (additional time penalty to brute-force keys at each stage) therefore no better than one layer of encryption, that is the outermost layer.

It provides one layer of encryption with a strength depending on password complexity.

• How is it security through obscurity? I'm not hiding anything. The encryption scheme is right there... Commented Mar 5, 2021 at 17:35
• That really depends on the password strength. Commented Mar 5, 2021 at 22:30