ご質問にお答えするにあたり、次の点にご注意ください。
PT(x) = Plain Text representation of 'x'
CT(x) = Cipher Text representation of 'x'
Bn = Logical Data Block 'n' in a sequence of multiple blocks.
1. IV とは何ですか?
IV はInitialization Vectorの短縮表記です。これは、いわゆる連鎖モードまたはフィードバックモードで暗号化を実行する対称ブロック暗号化アルゴリズムで使用されます。どちらの場合も、暗号化されたデータの前のブロックは、暗号化されるデータの次のブロックを変更する機能データ「グー」として使用されます。暗号化されたデータの連続する各ブロックには、使用するグーのブロブとして、以前に暗号化されたデータ ブロックが供給されます。しかし、平文の最初のブロックはどうでしょうか? 特製ソースは何を使っているの?答え: 関数に提供される IV です。絵的には、次のようになります。
CT(B1) = Encrypt(IV + PT(B1))
CT(B2) = Encrypt(CT(B1) + PT(B2))
CT(B3) = Encrypt(CT(B2) + PT(B3))
...
CT(Bn) = Encrypt(CT(Bn-1) + PT(Bn))
注: 上記の「+」は、前の暗号ブロックを次の平文ブロックに適用することを示します。それは数学的加算と考えるべきではありません。「組み合わせる」と考えてください。
IV のサイズは、使用されている対称アルゴリズムのブロック サイズと同じでなければなりません。AES-128-CFB と AES-256-CFB はどちらも 128 ビットのブロック サイズ (16 バイト) を使用します。したがって、IV は、この質問の目的のために 16 バイトのランダム グーである必要があり、安全な FIPS 準拠のランダム ソース アルゴリズムを使用して暗号化側で生成する必要があります。
2. 復号化のために IV を保存する必要はありますか?
はい。ただし、必ずしも最初に考えた方法とは限りません。最初の IV (提供されたもの)は何らかの方法で保持する必要があります。伝統的に、それがあるべきだと思う場所に正しく送信されます。暗号化されたデータの最初のブロックとして。これはしばしば人々を驚かせます。彼らは「でも、IV にデータを送信すると、安全ではないのではないか?」と考えます。このように考えてみてください。とにかく、いくつの「IV」を送りますか?各データ ブロックは、暗号化されたデータの前のブロックを IV として使用して暗号化されることに注意してください。したがって、実際には IV のストリーム全体を送信し、各暗号化ブロックは次の暗号化ブロックの IV などを送信しています。最初の IV が出力暗号文のどこにあるかはデータ表現の問題ですが、それがどこに行くかは最終的には関係ありません。質問。保存する必要があります。API が出力ストリームの一部としてこれを行う可能性があります (実際、まったく珍しいことではありません)。
3. データのブロックを暗号化するたびに *iv が変更されます。この変更された *iv をどうする必要がありますか?
私はあなたが使用している API に精通していませんが、次の暗号化に使用する IV が与えられているようです。これは、フィードバックまたは連鎖がブロックモード暗号化でどのように機能するかを考えると完全に理にかなっています。同じ IV を繰り返し使用しないでください。最後に返されたものを次のものとして使用します。API はその場で IV を変更しているため、送信する前に最初のIV を別の場所に保存するだけでよいようです。最初の暗号文ブロックをあなたの IV と比較します。それらが同じでない場合は、おそらく IV を送信し、次にデータ ストリームの暗号テキスト チェーンを送信し、最初のブロックが復号化の IV であることを受信者に認識させる必要があります。
4. 100MB 前後の大きなファイルを暗号化し、ランダムな *iv を初めて渡します。ループの残りの部分で同じ *iv を使用する必要がありますか、それとも、更新された *iv を使用する必要があります暗号化ブロックの最後の呼び出し。
(3) を参照してください。連続するブロックごとに更新された IV を使用します。
5. 最後に、構造化ファイルを扱っているので、バッファの長さとして Sizeof(struct) を使用するか、暗号化または復号化のバッファの長さとして sizeof(struct)*8 を使用する必要がありますか?
構造体のサイズを(ビットではなく)バイト単位で使用します。C/C++sizeof(yourstruct)
はこれを計算する必要がありますが、各構造を独立したエンティティとして (ファイル全体をまとめて暗号化するのではなく) 暗号化する場合、各暗号化には、説明のために追加される最小量のデータが含まれることに注意してください ( a)その構造に使用されるIV、および(b)PKCS5パディングを使用していると仮定して、最後のブロックを偶数ブロック境界までパディングします。したがって、暗号化された構造の正確なサイズは次のようになります。
IV + ((sizeof(struct) + 15)/16)*16) bytes.
繰り返しますが、これは、各構造を単一の暗号化として個別に暗号化して保存している場合であり、API がこの一部を説明する場合があります。
対称 AES の詳細については、Wiki の AES エントリを参照してください。CFB ブロック暗号モードの詳細については、同じサイトのBlock Cipher Modes of Operation の記事を参照してください。
これが役立つことを願っています。宿題をして、何よりも API がどのように機能するかを正確に学びましょう。