21

I know that many encryption algorithms, while secure, have vulnerabilities. To reduce risks, would multiple encryption like this

Blowfish_CbC ( Rc2_OFB ( AES128_CBC (myfilecontent)))

be a good idea?

I know that execution time seriously increases, but this isn't a problem for me. Any suggestions or ideas?

Mike Samuel
  • 3,873
  • 17
  • 25
Surfer on the fall
  • 787
  • 3
  • 8
  • 17
  • On the same PC - barely, if you encrypt it on one PC, and archive it and encrypt once more, it makes more sense. – Andrew Smith Aug 03 '12 at 11:41
  • @AndrewSmith I haven't understood. What are the differences if I use one or two computers? – Surfer on the fall Aug 03 '12 at 12:45
  • For example, you encrypt the data on the PC and encrypt it once. You copy it to the archive and encrypt it again. Data on your PC will disintegrate in 3 years, the data in the archive in the next 20. Assuming that your information goes over internet and gets recorded, you need to assume that at least one of the ciphers is decodable (the unknown factor), and you hide two private keys in two secure physical locations, so in case of well organized robbery, the data will stay secure as it's less likely to recover multiple keys, which this information can be even more protected. – Andrew Smith Aug 03 '12 at 13:13
  • And the point is not to store two keys on the same location / hardware machine, because when location / machine is stolen, the data is compromised anyway. – Andrew Smith Aug 03 '12 at 13:15
  • 5
    There are a few scenarios where multiple encryption makes sense. For example one layer for each hop of TOR. – CodesInChaos Aug 03 '12 at 13:40
  • 1
    @CodesInChaos That's different - you're using one algorithm multiple times in a layered-SSL-type protocol to ensure knowledge of payload and knowledge of identity are mutually exclusive to each node. Also, Tor was written by people with a lot of knowledge and experience in cryptography, and has seen a large amount of peer review. – Polynomial Aug 03 '12 at 18:12
  • OK but it could use different encryption, and THOR authors are not the authority as there isn't in science and they don't have monopol on multi-layer encryption. – Andrew Smith Aug 03 '12 at 18:16
  • What matters - thinking for yourself, just think about the location, the robbery of the key, and the security of the data. Simple probability calculation on a level of high school is enough to deduce it. It's not a rocket science actually. – Andrew Smith Aug 03 '12 at 18:17
  • 6
    @AndrewSmith your proliferation of misinformation around this subject is damaging. Your views (by evidence of voting) are clearly extreme. Furthermore, your conflictory attitude is becoming a burden to deal with. Please refrain. – Polynomial Aug 03 '12 at 18:18
  • http://code.google.com/p/mbe-metric-buttload-encryption-engine/ This might do what you want it to do.. –  Sep 25 '13 at 20:42

3 Answers3

17

By adding more algorithms, you do two things:

  1. Potentially increase the strength of the encryption.
  2. Increase the attack surface of your application.

AES128-CBC is strong. If you're implementing it properly, and using strong random keys and unique random IVs, you're very safe. The US government (NSA) certifies AES for use in securing top-secret documents. I somewhat doubt that your security requirements are anywhere near theirs, so you should consider AES more than strong enough alone. If you're really paranoid, move up to 256-bit AES.

Chaining algorithms only provides more provable security if you use independent keys for each. Using the same key for all ciphers means you still only have to bruteforce one key, though at 128 bits it's been predicted that we might never posess the equipment to do so.

Chaining multiple algorithms makes some sense in ridiculously high-security high-paranoia long term storage situations like TrueCrypt volumes, where the deployment environment is completely unknown. However, unless you're likely to be storing military secrets that'll be shipped into a hostile country, and happen to be a professional cryptographer, I'd stick with just using AES.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • Thank you very much for your very interesting answer... but is "Increase the attack surface of your application." valid if I choose different keys? P.S. according to [Schneier blog](http://www.schneier.com/blog/archives/2009/07/another_new_aes.html), AES 128 is more secure than AES-256!! – Surfer on the fall Aug 03 '12 at 08:49
  • 1
    Yes, the attack surface is still larger for independent keys. Essentially, the more stuff that you add to a scheme, the larger the attack surface. In respect to AES, Bruce said the security margin for AES128 would be higher than AES256 **for that single attack**, which is not effective against the full-round version of AES. The current best key-recovery attack on AES is still 2^126.1 operations for 128-bit and 2^254.4 operations for 256-bit, which is completely infeasible by any future standard. – Polynomial Aug 03 '12 at 09:08
  • 1
    @Polynomial, what about in a situation when you need to encrypt data that will be stored in a way that is accessible to everyone (ciphertext that is)? How can I ensure confidentiality for at least 20 years? – Matrix Aug 03 '12 at 09:10
  • 1
    @Matrix Even with ridiculously optimistic estimates of the increase in computing power that might appear over the next 100 years, it would still take several orders of magnitude longer to crack a 256-bit key than the amount of time the entire universe has existed. You cannot guarantee that AES will remain unbroken for that long, but are you *really* in a situation where you couldn't just re-encrypt it with whatever new standards are available in 10 years time? – Polynomial Aug 03 '12 at 09:12
  • 1
    @Polynomial, absolutely, data could be re-encrypted with newer algorithms over time, but nothing prevents a possible attacker from backing up ciphertext as it is now and trying to brake it 20 years from now. – Matrix Aug 03 '12 at 09:38
  • @Polynomial Very interesting. Could you explain me why Truecrypt, for example, provides [cascades](http://www.truecrypt.org/docs/?s=cascades) of algorithms? I think cryptography is really amazing, could you give me something to search on google about cascades of algorithms and their effectiveness? – Surfer on the fall Aug 03 '12 at 10:17
  • They do it because people are paranoid, and we're looking at very long term storage and unknown deployment scenarios with TrueCrypt. In this case, you *know* where you're deploying it, so you can tailor your security to the scenario. Cascades are as secure as their strongest link, but (as Thomas Pornin says below), you're introducing risk of implementation risks. – Polynomial Aug 03 '12 at 11:30
  • 1
    Not paranoid, it's rather denial of self-paranoid, AES128/256 is very likely to be cracked sooner or later with new methods and not before the universe ends but before we even migrate to better methods, just like with DES and others. That's why, if you encrypt twice, it's less likely that there will be method to restore two keys out of two ciphers at the same time, it is way much stronger encryption, and not paranoid, but reasonable for even mass usage in applications. – Andrew Smith Aug 03 '12 at 11:34
  • 1
    @AndrewSmith Which is why, if it is to be done, it should be implemented by a qualified cryptographer. – Polynomial Aug 03 '12 at 11:40
  • @Polynomial I agree, multiple encryption is usually not a good idea as it requires extra implementation complexity without providing more real-world security. But I don't see how `Blowfish(AES128(file))` has a larger attack surface than `AES128(file)`. Even if Blowfish was broken, attackers only can get an AES encrypted file. If instead AES is broken, you still need to decrypt Blowfish to get the AES encrypted file. I agree with your sentiment if it was Blowfish(file1), AES128(file2) or something. – dr jimbob Aug 03 '12 at 14:03
  • @Polynomial The only weakness I could somewhat see is if each encrypted file has a constant ASCII-armor header (`------BEGIN PGP ENCRYPTED MESSAGE--------`) that allows an attacker can do known-plaintext attacks that will slightly speed up each decryption except the final level. But this threat can be eliminated (don't encrypt guessable ASCII headers), and even if this wasn't done, its still as secure (or more secure) than the final level of encryption (assuming different keys are used in each step). If the same key is used for all steps, yes the known-plaintext part makes it weaker. – dr jimbob Aug 03 '12 at 14:06
  • @drjimbob It seems that you misunderstood. I'm not saying the *encryption* is weaker. I'm saying the *implementation* is *riskier*. More code = more potential for bugs = larger attack surface. – Polynomial Aug 03 '12 at 14:16
  • @Polynomial - it takes very few lines of code to properly chain together two encryption routines; for encryption/decryption (e.g., I did it in ~8 lines of python in my answer). You could argue that AES or Blowfish was implemented in pycrypto incorrectly; but in that case, its a big relief if you actually used multiple encryption to avoid that major implementation flaw (by using the other algorithm that doesn't have the major flaw). – dr jimbob Aug 03 '12 at 21:15
12

It is extremely rare that the algorithm itself is a vulnerability. Even weak algorithms such as RC4 are often the strongest part of the system in which they are used. Vulnerabilities usually hide in how you apply encryption (padding, IV randomness, integrity checks...) and in key management. These seemingly peripheral activities are quite hard to do right, and have repeatedly proven to be the number one source of weakness in any encryption system. By encrypting three times, you have tripled the opportunities for such nasty weaknesses.

So don't do it.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • No this is wrong, you cant tell that small part of the code is quite secure, because what matters is the weakest spot, which plays the role in the security chain. Encrypting twice is based on two keys, and two hierarchies and authority chains, therefore increasing security a lot. – Andrew Smith Aug 03 '12 at 11:39
  • 1
    Very good answer:I have a doubt. let's pretend I get first cipher encrypting some text with AES, then I encrypt first cipher with Blowfish and I get the second cipher. If I had implementation failures attacker could decrypt, exactly as with AES only encryption. Why do you say I have doubled oppurtinities for failure? Then, implementation risks can be exploited only if they have the direct cipher. – Surfer on the fall Aug 03 '12 at 12:38
  • 1
    Why could double encryption be more breakable than single encryption? I'm sure you're right, I'm a newbie, you're crypthographers, but I wish you explain me a little about this. Thank you again for your free help. – Surfer on the fall Aug 03 '12 at 12:41
  • 1
    It's not about the crypto itself. It's about the implementation of the crypto. Layman's explanation: if you write 100 lines of code to implement one algorithm, you've got 100 potential bugs. If you write 200 lines of code for 2 algorithms, and another 25 to chain them together, you've got 225 potential bugs. The potential for the crypto to fail (i.e. be discovered broken) is minuscule in comparison to the potential for your code to be buggy. – Polynomial Aug 03 '12 at 14:27
  • Now it's clearer to me @Polynomial , but if I use standard openssl php crypto, there shouldn't be implementation problems (except key management). Do you agree? – Surfer on the fall Aug 03 '12 at 16:08
  • That sounds reasonable, yes. – Polynomial Aug 03 '12 at 17:16
  • 1
    I still don't understand this reasoning. You're not going to be implementing the algorithms in any of the options but you would use a crypto library. So the options are 1) Ciphertext = Enc_Alg1(Key, Plaintext) or 2) Ciphertext = Enc_Alg2(Key, Plaintext) or 3) Ciphertext = Enc_Alg2(Key2, Enc_Alg1(Key1, Plaintext)). If 3) is any way less secure than the others then there must be a failure in either the implementation of Alg1 or in Alg1 itself because in that case the attacker could simply take your ciphertext and encrypt it with Alg2 and start attacking from there. – resistor Aug 06 '12 at 11:39
  • 1
    Also, you say that it is about the implementation and not the algorithm itself but wouldn't chaining the algorithms also help with implementation errors in either of the algorithms? Because in the scenario above if there is an implementation error in either Alg1 or Alg2 and you happen to have chosen that one then your encryption fails. But if you chain them then there would have to be an implementation error in both of them or else you would be fine. Again, if the chaining itself causes a problem I think that means the the first algorithm or implementation has already failed.What am I missing? – resistor Aug 06 '12 at 11:40
  • @thomas-pornin: I believe the underlying questions are : if you chain for example 2 algorithms (with different keys and cryptographic mechanisms), say "f()" and "g()" : could the resulting encryption be described as "done with cryptography function h" where h=g()of()? Then is it possible that trying to decrypt the encrypted file (resulting from applying "h()" algorithm to the original file) could directly give the original file? Thus I would understand it *could* be more unsecure, as "h" would not be "proven" to be safer than either "f" or "g", and could be possibly seriously flawed... – Olivier Dulac Sep 26 '13 at 07:57
12

Personally, I would avoid multiple encryption protocols most of the time. It adds significant extra implementation complexity without making your data any more secure in the real world, unless the encryption protocol you are using is ultimately broken or becomes computationally feasible at a later date to break.

Granted, I will disagree with others who claim that by doing so you have a larger attack surface and increase your vulnerabilities. While the attack surface technically does increase (you can attack blowfish; you can attack AES), since you must successfully attack both your security has not decreased. (Assuming your message is multiply-encrypted in a nested fashion (anything else doesn't make sense) with independent keys/passphrases like multiply_encrypted_file = Blowfish(AES(file)). If an attacker gets a hold of multiply_encrypted_file it is not in any way weaker than getting hold of encrypted_file = AES(file) though you should beware of exposing yourself to known-plaintext attacks which could weaken security if you used the same key/passphrase at all levels and have a guessable header/structure of the file after the first level of decryption). Even if they find a exploitable flaw in Blowfish encryption, they still only can reverse that and then find an AES encrypted file.

However, I do use multiple layers of encryption on an almost daily basis when there is a legitimate reason for it and it provides extra security. For example, I often need to connect to work computers from my home, but for security the work computers are on a private intranet, firewalled off from the outside world.

To connect, I first create a VPN tunnel over the public internet to a public facing VPN-server that verifies my identity that acts as a gateway to the intranet. Then all my network traffic sent over the internet between my house and work encrypted using IPsec protocol by VPN to the VPN server which decrypts it and forwards it to the local machine as if it was on the local intranet. However, I may then want to connect to something at work using ssh or https. This provides a layer of encryption for the local intranet at work, so my coworkers could not say eavesdrop in on my network connections. However, to someone at my ISP capturing packets the data they see has been multiply encrypted: VPN_encryption(ssh_encryption(actual_data_to_be_transferred)). Again, I'm not using the ssh protocol (on top of VPN) to make my data more secure against my ISP eavesdropping; but in no way does it make it easier for my ISP to eavesdrop).


EDIT: Some keeping arguing that implementation would be much tougher than standard encryption, but not necessarily. To demonstrate, I first implement Blowfish/AES in python using pycrypto:

from Crypto.Cipher import Blowfish, AES 
from Crypto import Random
from hashlib import sha256, sha512

def encrypt(plaintext, key, crypto_class):
    block_size = crypto_class.block_size
    iv = Random.new().read(block_size)
    cipher = crypto_class.new(key, crypto_class.MODE_CBC, iv)
    pad_len = block_size - (len(plaintext) % block_size)
    padding = ''.join([chr(pad_len)]*pad_len)
    encrypted_msg = iv + cipher.encrypt(plaintext + padding)
    return encrypted_msg

def decrypt(encrypted_msg, key, crypto_class):
    block_size = crypto_class.block_size
    iv = encrypted_msg[:block_size]
    cipher = crypto_class.new(key, crypto_class.MODE_CBC, iv)
    padded_msg = cipher.decrypt(encrypted_msg[block_size:])
    pad_len = ord(padded_msg[-1])
    msg = padded_msg[:len(padded_msg)-pad_len]
    return msg

which an be used in python like:

>>> plaintext = """CONFIDENTIAL INFO: Wall Street does insider trading.  Also, Israel has nuclear weapons."""
>>> passphrase = 'dinner artist mere trace metal thirty warp better'
>>> key1 = sha256(passphrase).digest()[0:16] # use 16-bytes=128bits for AES128 
>>> key2 = sha512(passphrase).digest()[0:56] # 56 bytes max for Blowfish.
# ideally independent keys but based on same passphrase for simplicity

>>> aes_encrypted_msg = encrypt(plaintext, key1, AES)           # '\r\xd0\x8e\x11\xbd\x9cN3\xd3\xa7a\xce\xd7\x15\xb4\xb2\xd7@\nBv\x95\xe0\xdb\xd0\xd2\xf2K\x9b\xcd\x80\xc0xr\xb7\x8d/\x16=\xfadV\xf0\xe2\xc8"x,\xa6\xf8\xed\x8b\xee#\xe1\xd1\xd4U4*0\x07\x11\x08\xc5\xe3\x98\r5\x018\xa5\xf1\x84\xb4\x90\xbc\x12\x80E\xbd\xe9\tN\xe1M\x92\xbb=\x06\r\xfe(\xe8\x12\xc7\x86=\n\x0f\x00\xa1R\xe6\x9c\xca\xaa\x15\xc1(\xaa\xe6'
>>> print decrypt(aes_encrypted_msg, key1, AES)
CONFIDENTIAL INFO: Wall Street does insider trading.  Also, Israel has nuclear weapons.

>>> blowfish_encrypted_msg = encrypt(plaintext, key2, Blowfish) # "a\xd2\xe5mf\xac\x81f\xe9Q\xbd.\xd9SwA\x8a)\xcc\x84S\x08\x00\x84\xc6Y\xf5\xa1\x16\x88JaUoF\t4\xa2\xf2b\x89s\xaa\xa6\xb3\xda\xe2\xdd\xff\x0f\xc2\xe2\x1dW\xf6\x840\xe9\x08Eje\xfa\x14\xb77\x99\x00a\xe0\xcd\xaf\xbe\x83\x08\xc0'\x81\x8b\x85\xf0\xdaxT\x94!o\xd0\x07\x0f#\xae$,\x91Q"
>>> print decrypt(blowfish_encrypted_msg, key2, Blowfish)
CONFIDENTIAL INFO: Wall Street does insider trading.  Also, Israel has nuclear weapons.

Now, you with minimal details you can implement something like:

def double_encrypt_using_keys(plaintext, key1, key2):
    tmp_encrypted_msg = encrypt(plaintext, key1, AES)    
    encrypted_msg = encrypt(tmp_encrypted_msg, key2, Blowfish)
    return encrypted_msg

def double_decrypt_using_keys(encrypted_msg, key1, key2):
    tmp_encrypted_msg = decrypt(encrypted_msg, key2, Blowfish)
    plaintext = decrypt(tmp_encrypted_msg, key1, AES)    
    return plaintext

def passphrase_to_keys(passphrase):
    return sha256(passphrase).digest()[0:16], sha512(passphrase).digest()[0:56]

def double_encrypt(plaintext, passphrase):        
    return double_encrypt_using_keys(plaintext, *passphrase_to_keys(passphrase))

def double_decrypt(encrypted_msg, passphrase):
    return double_decrypt_using_keys(encrypted_msg, *passphrase_to_keys(passphrase))

Which can be used like:

>>> double_encrypted_msg = double_encrypt(plaintext, passphrase) # '\xe9\xcd\x89\xed\xb1f\xd4\xbel\xcb\x8b2!\x98\xf0\xe7\xcd.\xefE\x1b\x92>\x82(\x8dG\xdaUS\x8f!\xe2rgkJ\xfb\xed\xb0\x10~n\xae\xe1\xce\x10\xf0\xa4K\x9f\xe6\xff\x8b\x7f\xdex]\x9a<\x9d\xc7\xa9\xb8\x9a\xbbx\xa4\xcekoA\xbc=)\xcc\xe6R\xd7\xb7\xd0[\xc3\xfc\xbfOU\x86\x18\xec5\xa9N\xed\xaa=\x9f\x06.\xbd\x0cMy\xcch\r\xf8\x8cR\xc0\xc5\xdeO\xef\xb0\xe01\x162\xaf\xf2\x1f\xd5\xb5"\x8a\xea\x96'
>>> print double_decrypt(double_encrypted_msg, passphrase)
CONFIDENTIAL INFO: Wall Street does insider trading.  Also, Israel has nuclear weapons.

I don't see how the multiply-encrypted implementation has more of an attack surface and is in anyway weaker than a singly-implemented one. The implementation to the outside world can still be enter a password to decrypt a stored file.

dr jimbob
  • 38,768
  • 8
  • 92
  • 161
  • Thanks, but a doubt again: you don't use ssh to make your data more secure, but technically they are more secure, since IPsec and ssh keys are different. Is this wrong? – Surfer on the fall Aug 03 '12 at 16:07
  • Our concerns weren't with the attack surface of the algorithms, but rather the attack surface of the implementations. – Polynomial Aug 03 '12 at 17:17
  • @Polynomial - I have written a basic implementation/example for encrypting and decrypting Blowfish_CBC and AES_CBC based on a single passphrase, above. Again, I don't think that multiple_encryption really gives much practical gain, but I see no way how multiple encryption makes it more vulnerable in any way. Please explain the larger attack surface of the above implementation. (Assume an application asks for a remembered passphrase and will encrypt/decrypt a stored file by calling these functions; exactly same attack surface as if the app asked for one passphrase to decrypt AES). – dr jimbob Aug 03 '12 at 21:08
  • One could argue that if there is no apparent benefit, why do it? The code *might* be simple to implement, but one must always account for human error. Introducing more code means the potential for more bugs and if there is no benefit - don't do it. –  Aug 04 '12 at 04:19
  • 1
    @TerryChia - There is an obvious benefit; if you fear some encryption algorithm in use now will break (e.g., in the 1970s DES was the predominant encryption standard approved by NIST; in the mid 1990s it was shown to be insecure). Even though the data I typically encrypt doesn't need this level of security doesn't ensure others will not need it (say the info needs to be unbreakable for two hundred years). The chaining code is as simple to implement as key strengthening a password hash, and I remain unconvinced that it introduces a larger attack surface. – dr jimbob Aug 06 '12 at 05:08