Personalmente, eviterei più protocolli di crittografia per la maggior parte del tempo. Aggiunge una notevole complessità aggiuntiva all'implementazione senza rendere i tuoi dati più sicuri nel mondo reale, a meno che il protocollo di crittografia che stai utilizzando non sia in definitiva rotto o diventa potenzialmente fattibile in un secondo momento per rompere.
Certo, non sono d'accordo con gli altri che sostengono che così facendo si ha una superficie di attacco più grande e si aumentano le proprie vulnerabilità. Mentre tecnicamente la superficie di attacco aumenta (puoi attaccare blowfish, puoi attaccare AES), dal momento che devi attaccare con successo sia la tua sicurezza non sia diminuita. (Supponendo che il tuo messaggio sia crittografato in più modi in modo annidato (qualsiasi altra cosa non ha senso) con chiavi indipendenti / passphrase come multiply_encrypted_file = Blowfish(AES(file))
. Se un utente malintenzionato ottiene una sospensione di file crittografato, non è in alcun modo più debole di encrypted_file = AES(file)
anche se dovresti fare attenzione a esponendoti agli attacchi in testo normale che potrebbe indebolire la sicurezza se si utilizza la stessa chiave / passphrase a tutti i livelli e si ha un'intestazione / struttura ipotetica del file dopo il primo livello di decrittografia). Anche se trovano una vulnerabilità sfruttabile in Blowfish
di crittografia, possono comunque solo invertirla e quindi trovare un file crittografato AES.
Tuttavia, faccio uso di più livelli di crittografia su base quasi giornaliera quando esiste una ragione legittima e fornisce una maggiore sicurezza. Ad esempio, ho spesso bisogno di collegarmi a computer di lavoro da casa, ma per sicurezza i computer di lavoro sono su una intranet privata, protetta dal mondo esterno.
Per connetterti, prima creo un tunnel VPN sulla intranet pubblica su un server VPN pubblico che verifica la mia identità che funge da gateway per l'intranet. Quindi tutto il mio traffico di rete inviato su Internet tra casa mia e lavoro crittografato tramite protocollo IPsec da VPN al server VPN che lo decrittografa e lo inoltra al computer locale come se fosse sulla intranet locale. Tuttavia, potrei quindi collegarmi a qualcosa al lavoro usando ssh
o https
. Questo fornisce un livello di crittografia per l'intranet locale al lavoro, quindi i miei colleghi non potevano dire di origliare nelle mie connessioni di rete. Tuttavia, per qualcuno del mio ISP che cattura i pacchetti, i dati che visualizzano sono stati crittografati in più modi: VPN_encryption(ssh_encryption(actual_data_to_be_transferred))
. Ancora una volta, non sto usando il protocollo SSH per la crittografia per rendere i miei dati più sicuri contro l'intercettazione del mio ISP; ma in nessun modo rende più facile origliare il mio ISP.
EDIT:
Alcuni continuano a sostenere che l'implementazione sarebbe molto più difficile della crittografia standard, ma non necessariamente. Per dimostrare, prima implemento Blowfish / AES in 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
che può essere usato in Python come:
>>> 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.
Ora, con i dettagli minimi puoi implementare qualcosa del tipo:
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))
Che può essere usato come:
>>> 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.
Non vedo come l'implementazione con crittografia multipla abbia più di una superficie di attacco ed è comunque più debole di una versione implementata singolarmente. L'implementazione all'esterno può ancora inserire una password per decodificare un file memorizzato.