Personalmente, evitaría múltiples protocolos de cifrado la mayor parte del tiempo. Agrega una complejidad de implementación adicional significativa sin hacer que sus datos sean más seguros en el mundo real, a menos que el protocolo de cifrado que está utilizando finalmente se rompa o se vuelva computacionalmente viable en una fecha posterior.
Por supuesto, no estaré de acuerdo con otras personas que afirman que, al hacerlo, tienen una mayor superficie de ataque y aumentan sus vulnerabilidades. Si bien la superficie de ataque aumenta técnicamente (puede atacar pez globo; puede atacar AES), ya que debe atacar con éxito, ya que su seguridad no ha disminuido. (Suponiendo que su mensaje se cifre de forma anidada de manera anidada (cualquier otra cosa no tiene sentido) con claves / frases de contraseña independientes como multiply_encrypted_file = Blowfish(AES(file))
. Si un atacante obtiene un archivo cifrado no es más débil que obtenerlo. encrypted_file = AES(file)
, aunque debes tener cuidado con exponiéndote a ataques de texto claro conocidos que podría debilitar la seguridad si usara la misma clave / frase de contraseña en todos los niveles y tenga un encabezado / estructura adivinable del archivo después del primer nivel de descifrado). Incluso si encuentran una falla explotable en el cifrado Blowfish
, todavía pueden revertir eso y luego encontrar un archivo cifrado AES.
Sin embargo, uso múltiples capas de cifrado casi a diario cuando existe una razón legítima para ello y proporciona seguridad adicional. Por ejemplo, a menudo necesito conectarme a las computadoras del trabajo desde mi casa, pero por seguridad, las computadoras del trabajo están en una intranet privada, con firewall fuera del mundo exterior.
Para conectarme, primero creo un túnel VPN a través de la intranet pública a un servidor VPN público que verifica mi identidad que actúa como puerta de entrada a la intranet. Luego, todo el tráfico de mi red enviado a través de Internet entre mi casa y el trabajo se cifró mediante el protocolo IPsec mediante VPN al servidor VPN, que lo descifra y lo reenvía a la máquina local como si estuviera en la intranet local. Sin embargo, es posible que desee conectarme a algo en el trabajo utilizando ssh
o https
. Esto proporciona una capa de encriptación para la intranet local en el trabajo, por lo que mis compañeros de trabajo no pudieron comentar a escondidas mis conexiones de red. Sin embargo, para alguien en mi ISP que captura paquetes, los datos que ven se han cifrado de manera múltiple: VPN_encryption(ssh_encryption(actual_data_to_be_transferred))
. Nuevamente, no estoy usando el protocolo ssh para el cifrado para hacer que mis datos estén más seguros contra las escuchas ilegales de mi ISP; pero de ninguna manera hace que sea más fácil para mi ISP escuchar a escondidas).
EDITAR:
Algunos sostienen que la implementación sería mucho más difícil que el cifrado estándar, pero no necesariamente. Para demostrar, primero implemento Blowfish / AES en python usando 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
que se puede usar en python como:
>>> 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.
Ahora, con detalles mínimos, puedes implementar algo como:
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))
Que se puede utilizar como:
>>> 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.
No veo cómo la implementación de cifrado múltiple tiene más de una superficie de ataque y es de alguna manera más débil que una implementada individualmente. La implementación en el mundo exterior aún puede introducirse una contraseña para descifrar un archivo almacenado.