AES暗号化モード(CBC ECB CTR OCB CFB)を選択するにはどうすればいいですか?[closed] 質問する

AES暗号化モード(CBC ECB CTR OCB CFB)を選択するにはどうすればいいですか?[closed] 質問する

どのような状況でどちらが好まれるのでしょうか?

さまざまなモードの評価基準のリストと、各基準の適用可能性に関する議論を見たいと思います。

たとえば、暗号化と復号化の「コードのサイズ」は基準の 1 つだと思います。これは、802.11 ネットワーク アダプタなどのマイクロコード組み込みシステムにとって重要です。CBC を実装するために必要なコードが CTR に必要なコードよりもはるかに小さい場合 (これが本当かどうかはわかりませんが、これは単なる例です)、コードの小さいモードが好まれる理由は理解できます。ただし、サーバー上で実行されるアプリを作成し、使用している AES ライブラリが CBC と CTR の両方を実装している場合、この基準は無関係です。

「評価基準のリストと各基準の適用可能性」の意味がわかりますか?

これは実際にはプログラミングに関連するものではなく、アルゴリズムに関連するものです。

ベストアンサー1

独自の暗号化を実装できない場合は、慎重に検討してください。

残念なことに、この質問をしているのであれば、安全なシステムを設計して実装することはできないでしょう。

私の主張を説明しましょう。Web アプリケーションを構築していて、セッション データを保存する必要があると想像してください。各ユーザーにセッション ID を割り当て、セッション ID をセッション データにマッピングするハッシュ マップでサーバー上のセッション データを保存できます。ただし、サーバー上でこの厄介な状態に対処する必要があり、ある時点で複数のサーバーが必要になると、状況が複雑になります。そのため、代わりにクライアント側の Cookie にセッション データを保存するというアイデアがあります。もちろん、ユーザーがデータを読み取って操作できないように暗号化します。では、どのモードを使用すればよいでしょうか。ここに来て、一番上の回答を読みました (myforwik さん、あなただけを取り上げてしまって申し訳ありません)。最初に取り上げた ECB はあなたには適していません。複数のブロックを暗号化したいのです。次の CBC は良さそうですが、CTR の並列処理は必要なく、ランダム アクセスも必要ありません。したがって、XTS は不要で、特許は面倒なので、OCB は不要です。暗号ライブラリを使用すると、ブロックサイズの倍数しか暗号化できないため、パディングが必要であることがわかります。PKCS7なぜなら、CBCはいくつかの重要な暗号規格で定義されているからです。どこかでCBCが証明可能な安全性 if used with a random IV and a secure block cipher, you rest at ease even though you are storing your sensitive data on the client side.

Years later after your service has indeed grown to significant size, an IT security specialist contacts you in a responsible disclosure. She's telling you that she can decrypt all your cookies using a padding oracle attack, because your code produces an error page if the padding is somehow broken.

This is not a hypothetical scenario: Microsoft had this exact flaw in ASP.NET until a few years ago.

The problem is there are a lot of pitfalls regarding cryptography and it is extremely easy to build a system that looks secure for the layman but is trivial to break for a knowledgeable attacker.

What to do if you need to encrypt data

For live connections use TLS (be sure to check the hostname of the certificate and the issuer chain). If you can't use TLS, look for the highest level API your system has to offer for your task and be sure you understand the guarantees it offers and more important what it does not guarantee. For the example above a framework like Play offers client side storage facilities, it does not invalidate the stored data after some time, though, and if you changed the client side state, an attacker can restore a previous state without you noticing.

If there is no high level abstraction available use a high level crypto library. A prominent example is NaCl and a portable implementation with many language bindings is Sodium. Using such a library you do not have to care about encryption modes etc. but you have to be even more careful about the usage details than with a higher level abstraction, like never using a nonce twice. For custom protocol building (say you want something like TLS, but not over TCP or UDP) there are frameworks like Noise and associated implementations that do most of the heavy lifting for you, but their flexibility also means there is a lot of room for error, if you don't understand in depth what all the components do.

If for some reason you cannot use a high level crypto library, for example because you need to interact with existing system in a specific way, there is no way around educating yourself thoroughly. I recommend reading Cryptography Engineering by Ferguson, Kohno and Schneier. Please don't fool yourself into believing you can build a secure system without the necessary background. Cryptography is extremely subtle and it's nigh impossible to test the security of a system.

Comparison of the modes

Encryption only:

  • Modes that require padding: Like in the example, padding can generally be dangerous because it opens up the possibility of padding oracle attacks. The easiest defense is to authenticate every message before decryption. See below.
    • ECB encrypts each block of data independently and the same plaintext block will result in the same ciphertext block. Take a look at the ECB encrypted Tux image on the ECB Wikipedia page to see why this is a serious problem. I don't know of any use case where ECB would be acceptable.
    • CBC has an IV and thus needs randomness every time a message is encrypted, changing a part of the message requires re-encrypting everything after the change, transmission errors in one ciphertext block completely destroy the plaintext and change the decryption of the next block, decryption can be parallelized / encryption can't, the plaintext is malleable to a certain degree - this can be a problem.
  • Stream cipher modes: These modes generate a pseudo random stream of data that may or may not depend the plaintext. Similarly to stream ciphers generally, the generated pseudo random stream is XORed with the plaintext to generate the ciphertext. As you can use as many bits of the random stream as you like you don't need padding at all. Disadvantage of this simplicity is that the encryption is completely malleable, meaning that the decryption can be changed by an attacker in any way he likes as for a plaintext p1, a ciphertext c1 and a pseudo random stream r and attacker can choose a difference d such that the decryption of a ciphertext c2=c1⊕d is p2 = p1⊕d, as p2 = c2⊕r = (c1 ⊕ d) ⊕ r = d ⊕ (c1 ⊕ r). Also the same pseudo random stream must never be used twice as for two ciphertexts c1=p1⊕r and c2=p2⊕r, an attacker can compute the xor of the two plaintexts as c1⊕c2=p1⊕r⊕p2⊕r=p1⊕p2. That also means that changing the message requires complete reencryption, if the original message could have been obtained by an attacker. All of the following steam cipher modes only need the encryption operation of the block cipher, so depending on the cipher this might save some (silicon or machine code) space in extremely constricted environments.
    • CTR is simple, it creates a pseudo random stream that is independent of the plaintext, different pseudo random streams are obtained by counting up from different nonces/IVs which are multiplied by a maximum message length so that overlap is prevented, using nonces message encryption is possible without per message randomness, decryption and encryption are completed parallelizable, transmission errors only effect the wrong bits and nothing more
    • OFB also creates a pseudo random stream independent of the plaintext, different pseudo random streams are obtained by starting with a different nonce or random IV for every message, neither encryption nor decryption is parallelizable, as with CTR using nonces message encryption is possible without per message randomness, as with CTR transmission errors only effect the wrong bits and nothing more
    • CFBの疑似ランダム ストリームはプレーンテキストに依存し、CTR や OFB と同様に、メッセージごとに異なる nonce またはランダム IV が必要です。nonce を使用すると、メッセージごとのランダム性なしでメッセージの暗号化が可能になり、復号化は並列化できますが、暗号化は並列化できません。送信エラーにより、次のブロックが完全に破壊されますが、現在のブロックの間違ったビットにのみ影響します。
  • ディスク暗号化モード: これらのモードは、ファイル システム抽象化の下にあるデータを暗号化するために特化されています。効率上の理由から、ディスク上の一部のデータを変更するには、最大で 1 つのディスク ブロック (512 バイトまたは 4kib) の書き換えのみが必要です。これらは、他のモードとは使用シナリオが大きく異なるため、この回答の範囲外です。ブロックレベルのディスク暗号化以外には使用しないでくださいメンバーの一部: XEX、XTS、LRW。

認証された暗号化:

パディングオラクル攻撃や暗号文の変更を防ぐために、メッセージ認証コード(MAC)を暗号文にかけ、改ざんされていない場合にのみ復号化します。これは暗号化してからMACと呼ばれ、他の順序よりも優先されるべきであるごくわずかな使用例を除き、信頼性は機密性と同じくらい重要です (後者は暗号化の目的です)。認証された暗号化スキーム (関連データ (AEAD) 付き) は、暗号化と認証の 2 つのプロセスを 1 つのブロック暗号モードに統合し、プロセス中に認証タグも生成します。ほとんどの場合、これにより速度が向上します。

  • CCM は、CTR モードと CBC-MAC の単純な組み合わせです。ブロックごとに 2 つのブロック暗号暗号化を使用するため、非常に低速です。
  • OCBは高速ですが、特許の制約があります。無料(自由という意味)または非軍事ソフトウェアの場合、特許所有者は無料ライセンスを付与しました、 けれど。
  • GCMはCTRモードとGHASH(2^128要素のガロア体上のMAC)を組み合わせた非常に高速だが、複雑とも言える。TLS 1.2のような重要なネットワーク標準で広く使用されていることは、特別命令Intel は GHASH の計算を高速化するために導入しました。

おすすめ:

認証の重要性を考慮すると、ほとんどのユースケース(ディスク暗号化目的を除く)では、次の 2 つのブロック暗号モードをお勧めします。データが非対称署名によって認証される場合は CBC を使用し、そうでない場合は GCM を使用します。

おすすめ記事