2012-04-24 11 views
1

私はCでサーバを書いています。エースでファイルをエンコードしたいと思います。AESでファイルをエンコードする

私が知っているように、エンコードブロックのサイズはAESキーの長さと同じでなければならないので、最後のブロックを必要なサイズの0で補う必要があります。問題はデコードにあります:ファイルの内容と補数のゼロを区別する方法は?まあ、その目的のためにBase64エンコーディングを使うつもりでしたが、大きなファイルではそれほど遅くないのですか?エンコードされたブロックを送信する前にファイルサイズを送信する必要がありますか?

+2

*これは正しくありません*「私は、符号化ブロックサイズは、AESキーの長さに等しくなければならない知っているように、」キーサイズは128であるとして、AESのブロックサイズは常に128ビットであり、192または256ビットです。 – ouah

答えて

3

一般的なスキームはPKCS#5パディングです。基本的には、(平文の)パディングを、パディング長と等しいバイトで埋める。次に、復号化の後、最後のバイトを見て、どれだけ削除するかを確認します。ドロップされたバイトが同じであることを確認することで、迅速なサニティチェックが可能になります。いくつかの例:16進数:

[AABBCCDD EEFF0011 22334455 667788--] -> [AABBCCDD EEFF0011 22334455 66778801] 
[AABBCCDD EEFF0011 22334455 66------] -> [AABBCCDD EEFF0011 22334455 66030303] 
[AABBCCDD EEFF0011 22334455 66778899] -> [AABBCCDD EEFF0011 22334455 66778899][10101010 10101010 10101010 10101010] 
//the last byte must be padding, even if that requires an extra block 

サイドノート:暗号化を自分で実装する場合は、操作モードも参照してください。そうでない場合は、使用しているライブラリによってパディングを処理できるはずです。

+0

ありがとうございます。 OpenSSLを使ってそのようなパディングの例を投稿できますか? – user1256821

+0

私は尋ねる人ではありません - 私はしばらくのうちにCに触れていません。私はコマンドラインからOpenSSLだけを使用しました。オンラインで、おそらく[こちら](http://www.openssl.org/docs/crypto/EVP_EncryptInit.html)を開始し、試してみてください。 – maybeWeCouldStealAVan

+1

PKCS#5のパディング(またはAESの正式なPKCS#7パディング)では、常に*パッドが使用されます。さもなければ、あなたはまだできません。パディングから01に設定されたブロックの最後の1バイトを区別する。したがって、16バイト(ブロックサイズ)のプレーンテキストは、完全な32バイトにパディングされます。 PKCS#7パディングは、通常、CBCモード暗号化に使用される。 CTRモードの暗号化では埋め込みは不要です。 –

2

Base64でファイルをエンコードし、AESで暗号化するのは良い考えではありません。そうすることで、cyphertextの各バイトの上位2ビットを既知の値に設定することによって、可能なブロックの数を2^64から2^48に減らします。

私はそれが "最高"または "普通"の方法であるかどうかはわかりませんが、一般的に、私の暗号文の最初または最後にいくつかのブロックを叩いてメタデータを解読しますファイルのサイズ、ファイル名、コンテンツの種類などです。はい、これらのブロックはエントロピーはほとんどありませんが、各バイトに1つまたは2つのブロックを含めるよりもはるかに優れています。

たとえば、ファイルの長さが10バイトの場合、2バイトの有効バイトと6バイトのパディングを含むブロックが1つのフルテキストブロックになります。最後のブロックにはメタデータが含まれます。 (実際には、メタデータブロックは最初または最後に行くことができます。)

+0

実際、このような理由から暗号化する前にデータを圧縮するのは良い方法と考えています。 Base64は逆のことを行い、より多くのブロックにわたって情報を拡張します。ヘッダーの低エントロピーに関しては、ブロック暗号動作モード(例えば、CBC)の正しい使用法がそれを扱うべきである。 – maybeWeCouldStealAVan

0

パディング方式については、このページを見る:

http://en.wikipedia.org/wiki/Padding_(cryptography

を例えばCBCモード用:

一つの方法は、ゼロに続く1ビットと最後のブロックを記入しますビット。入力がブロック全体をいっぱいにした場合、パディングに対応するために「ダミーブロック」が追加されます。そうしないと、入力平文の終わりがパディングとして誤って解釈される可能性があります。別の方法は、完全なブロックを埋めるために平文の終わりにnバイト(n-1)の値を付加することです。メッセージがすでにブロックを完全に満たす場合、以前と同じ理由で、ブロックの完全ブロックが追加されます。これは、パディングが0の1バイトまたは1の2バイトのいずれかであることを意味します。

CTRモードを使用する場合、暗号テキストはプレーンテキストと同じサイズであるため、パディングは不要です。

@maybewecouldstealavanで述べたように、一般的なパディングスキームはRSA LaboratoriesのPKCS#5です。これは、OpenSSLプログラムがCBCモードで使用する埋め込みスキームです。

すべてのブロック暗号は、通常、標準ブロックパディングとも呼ばれるPKCS#5パディングを使用します。これにより、基本整合性またはパスワードチェックを実行できます。

http://www.openssl.org/docs/apps/enc.html

+0

引用符で囲まれたOpenSSLドキュメントについて:「標準ブロックパディング」として知られておらず、基本的な完全性またはパスワードのチェックとしてそれを使用するのはばかげてばかげている。可能であれば、OpenSSL自体の説明を得ることさえできない場合、OpenSSLのドキュメントに頼らないでください。それは絶対的な罠です。 –

+0

ああ、PKCS#5のパディングは実際には8バイトのブロックサイズの暗号です。 AESの場合、PKCS#7のパディングとして正式に知られていますが、これらの用語はAPI内でも互換性をもって使用されます。 –

関連する問題