web-dev-qa-db-ja.com

複数の暗号化は良い考えですか?

多くの暗号化アルゴリズムは安全ではありますが、脆弱性があることを知っています。リスクを減らすために、このような複数の暗号化は

Blowfish_CbC ( Rc2_OFB ( AES128_CBC (myfilecontent)))

いいアイデアですか?

実行時間が大幅に増加することは知っていますが、これは問題ではありません。提案やアイデアはありますか?

20

個人的には、ほとんどの場合、複数の暗号化プロトコルを避けます。使用している暗号化プロトコルが最終的に破損したり、後で破損したりして計算上実行可能になった場合を除き、現実の世界でデータのセキュリティを強化することなく、実装の複雑さが大幅に増大します。

確かに、そうすることで攻撃面が大きくなり、脆弱性が増えると主張する人には反対します。技術的に攻撃面は増加しますが(フグを攻撃できます; AESを攻撃できます)、両方の攻撃を成功させる必要があるため、セキュリティは低下していません。 (メッセージがmultiply_encrypted_file = Blowfish(AES(file))のような独立したキー/パスフレーズでネストされた方法で多重暗号化されていると仮定します(他のものは意味がありません)。攻撃者が_multiply_encrypted_file_を保持している場合、何らかの方法でencrypted_file = AES(file)を取得するよりも弱いですが、 既知の平文攻撃に身をさらす は、すべてのレベルで同じキー/パスフレーズを使用した場合にセキュリティを弱める可能性があり、解読の最初のレベルの後で、ファイルの推測可能なヘッダー/構造を持っている)。彼らがBlowfish暗号化に悪用可能な欠陥を見つけたとしても、それを取り消すことができ、AES暗号化ファイルを見つけることができます。

ただし、正当な理由があり、追加のセキュリティが提供される場合は、ほぼ毎日、暗号化の複数のレイヤーを使用します。たとえば、自宅から仕事用のコンピュータに接続する必要があることがよくありますが、セキュリティのために仕事用のコンピュータはプライベートイントラネット上にあり、外界からファイアウォールで保護されています。

接続するには、まずパブリックインターネットを介して、イントラネットへのゲートウェイとして機能する自分の身元を確認するパブリックに面したVPNサーバーへのVPNトンネルを作成します。次に、自宅と職場の間でインターネット経由で送信されたすべてのネットワークトラフィックは、IPsecプロトコルを使用してVPNによって暗号化され、VPNサーバーにVPNサーバーによって暗号化されて復号化され、ローカルイントラネット上にあるかのようにローカルマシンに転送されます。ただし、sshまたはhttpsを使用して職場で何かに接続したい場合があります。これにより、職場のローカルイントラネットに暗号化のレイヤーが提供されるため、同僚は私のネットワーク接続を盗聴したとは言えませんでした。ただし、パケットをキャプチャしているISPの誰かにとって、彼らが見るデータは多重暗号化されています:VPN_encryption(ssh_encryption(actual_data_to_be_transferred))。繰り返しますが、ISPの盗聴に対してデータをより安全にするために(VPNの上に)sshプロトコルを使用していません。しかし、それによって私のISPの盗聴が容易になるわけではありません。


編集:実装は標準の暗号化よりもはるかに難しいと主張する人もいますが、必ずしもそうではありません。実例として、まずBlowfish/AESをpythonを使用して 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
_

pythonのように使用できます:

_>>> 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.
_

これで、最小限の詳細で次のようなものを実装できます。

_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))
_

次のように使用できます:

_>>> 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.
_

多重に暗号化された実装がどのように攻撃面を持ち、いずれにしても単一実装のものよりも弱いのかはわかりません。外部への実装では、保存されたファイルを復号化するためのパスワードを入力することができます。

11
dr jimbob

さらにアルゴリズムを追加することにより、2つのことを行います。

  1. 潜在的暗号化の強度を高めます。
  2. アプリケーションの攻撃面を増やします。

AES128-CBCは強力です。適切に実装していて、強力なランダムキーと一意のランダムIVを使用している場合は、非常に安全です。米国政府(NSA)は、最高機密文書の保護に使用するAESを認定しています。あなたのセキュリティ要件が彼らの近くにあるとは少し疑わしいので、AESを単独で十分に強力なものよりも考慮する必要があります。本当に偏執的である場合は、最大256ビットのAESに移行してください。

連鎖アルゴリズムは、それぞれに独立したキーを使用する場合にのみ、より証明可能なセキュリティを提供します。すべての暗号に同じ鍵を使用することは、1つの鍵をブルートフォースするだけでよいことを意味しますが、128ビットでは、そうするために機器を装うことは決してないだろうと予測されています。

複数のアルゴリズムをチェーンすることは、TrueCryptボリュームのような、セキュリティが非常に高く、パラノイアが高い長期的なストレージ状況では、展開環境が完全に不明であるので、ある程度理にかなっています。ただし、敵国に出荷される軍事秘密を保管している可能性が高く、たまたまプロの暗号技術者である場合を除き、私はAESのみを使用します。

16
Polynomial

アルゴリズム自体が脆弱性であることは非常にまれです。 RC4などの弱いアルゴリズムでさえ、それらが使用されるシステムの最も強力な部分であることがよくあります。通常、脆弱性はhow非表示に暗号化(パディング、IVランダム性、整合性チェック...)とキー管理に適用されます。これらの一見周辺的なアクティビティは正しく実行するのが非常に難しく、暗号化システムの弱点の最大の原因であることが繰り返し証明されています。 3回暗号化することで、このような厄介な弱点の機会が3倍になりました。

だからそれをしないでください。

13
Thomas Pornin