12,964
回編集
(→概要) |
(→OFBモード) |
||
79行目: | 79行目: | ||
<br> | <br> | ||
カウンタモードであれば、安全性が若干損なう可能性があるが、暗号化も復号もランダムに行えて便利である。<br> | カウンタモードであれば、安全性が若干損なう可能性があるが、暗号化も復号もランダムに行えて便利である。<br> | ||
<br><br> | |||
== 暗号化ライブラリ == | |||
==== Crypto++ Libraryのダウンロード ==== | |||
[https://cryptopp.com Crypto++ Libraryの公式Webサイト]にアクセスして、暗号化ライブラリのソースコードをダウンロードする。<br> | |||
ダウンロードしたソースコードをビルドする。<br> | |||
make -j 8 static dynamic CXX=/<GCCのインストールディレクトリ>/g++ | |||
make test | |||
make install DESTDIR=<暗号化ライブラリのインストールディレクトリ> | |||
<br> | |||
暗号化ライブラリの使用手順は、以下のWebサイトを参照すること。<br> | |||
https://www.cryptopp.com/wiki/Advanced_Encryption_Standard<br> | |||
<br> | |||
==== Crypto++ Libraryの概要 ==== | |||
AES(またはその他のブロック暗号)を使用する時は、通常、ブロック暗号のインスタンスを持つモードを使用する。<br> | |||
例えば、CFBモードの場合は、以下のように記述する。<br> | |||
<syntaxhighlight lang="c++"> | |||
CFB_Mode<AES>::Encryption Encrypt; // CFB_Modeは、ブロック暗号をテンプレートパラメータとして受け取る | |||
</syntaxhighlight> | |||
<br> | |||
==== ブロック暗号の参照 ==== | |||
外部のブロック暗号オブジェクトのインスタンスではなく、そのオブジェクトへの参照を保持するモードオブジェクトを作成することもできる。<br> | |||
以下の例では、外部のAESオブジェクトでCFBモードを使用している。<br> | |||
<syntaxhighlight lang="c++"> | |||
AES::Encryption aesEncryption(key, AES::DEFAULT_KEYLENGTH); | |||
CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv); | |||
</syntaxhighlight> | |||
<br> | |||
ExternalCipherモードは、WindowsでFIPSをサポートするために追加されたものであり、必要がない限り避けるべきである。<br> | |||
<br> | |||
==== ECBおよびCBCモードの備考 ==== | |||
ECBおよびCBCモードでは、データをブロックサイズの倍数で処理する必要がある。<br> | |||
または、<code>StreamTransformationFilter</code>をモードオブジェクトにラッピングして、フィルタオブジェクトとして使用することもできる。<br> | |||
<code>StreamTransformationFilter</code>は、データをブロックにバッファリングして、必要に応じてパディングを行う。<br> | |||
<br> | |||
もし、フルブロックサイズで処理する(パディングを行わない)場合は、第4引数に<code>StreamTransformationFilter</code>の<code>NO_PADDING</code>を指定する。<br> | |||
<syntaxhighlight lang="c++"> | |||
StringSource(data, true, new StreamTransformationFilter(encryptor, new StringSink(result), NO_PADDING)) | |||
</syntaxhighlight> | |||
<br> | |||
==== サンプルコード ==== | |||
以下の例では、AESが使用する鍵長の最小値、最大値、標準値をダンプしている。(2番目と3番目はパイプラインのフィルターを使用している)<br> | |||
パイプラインは高レベルの抽象化であり、入力のバッファリング、出力のバッファリング、パディングを処理する。<br> | |||
<syntaxhighlight lang="c++"> | |||
std::cout << "鍵長 : " << AES::DEFAULT_KEYLENGTH << std::endl; | |||
std::cout << "鍵長(最小) : " << AES::MIN_KEYLENGTH << std::endl; | |||
std::cout << "鍵長(最大) : " << AES::MAX_KEYLENGTH << std::endl; | |||
std::cout << "ブロックサイズ : " << AES::BLOCKSIZE << std::endl; | |||
// 出力 | |||
// 標準値の鍵長は128ビット(16バイト) | |||
鍵長 : 16 | |||
鍵長(最小) : 16 | |||
鍵長(最大) : 32 | |||
ブロックサイズ : 16 | |||
</syntaxhighlight> | |||
<br> | |||
以下の例では、CFBモードを使用して、暗号化および復号を行っている。<br> | |||
ECBやCBCではないため、データ長をAESのブロックサイズの倍数にする必要は無い。<br> | |||
<syntaxhighlight lang="c++"> | |||
AutoSeededRandomPool rnd; | |||
// Generate a random key | |||
SecByteBlock key(0x00, AES::DEFAULT_KEYLENGTH); | |||
rnd.GenerateBlock(key, key.size()); | |||
// Generate a random IV | |||
SecByteBlock iv(AES::BLOCKSIZE); | |||
rnd.GenerateBlock(iv, iv.size()); | |||
byte plainText[] = "Hello! How are you."; | |||
size_tmessageLen = std::strlen((char*)plainText) + 1; | |||
// Encrypt | |||
CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv); | |||
cfbEncryption.ProcessData(plainText, plainText, messageLen); | |||
// Decrypt | |||
CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv); | |||
cfbDecryption.ProcessData(plainText, plainText, messageLen); | |||
</syntaxhighlight> | |||
<br> | |||
ここでは、外部で生成された鍵と初期化ベクトル(IV)を使用して、暗号化器と復号器を取得する例を記述する。<br> | |||
その後の処理は、上記の例と同様に記述する。<br> | |||
<syntaxhighlight lang="c++"> | |||
SecByteBlock aes_key(16); | |||
SecByteBlock iv(16); | |||
// stub for how you really get it, e.g. reading it from a file, off of a | |||
// network socket encrypted with an asymmetric cipher, or whatever | |||
read_key(aes_key, aes_key.size()); | |||
// stub for how you really get it, e.g. filling it with random bytes or | |||
// reading it from the other side of the socket since both sides have | |||
// to use the same IV as well as the same key | |||
read_initialization_vector(iv); | |||
// the final argument is specific to CFB mode, and specifies the refeeding size in bytes. | |||
// This invocation corresponds to Java's Cipher.getInstance("AES/CFB8/NoPadding") | |||
auto enc = new CFB_Mode<AES>::Encryption(aes_key, sizeof(aes_key), iv, 1); | |||
// the final argument is specific to CFB mode, and specifies the refeeding size in bytes. | |||
// This invocation corresponds to Java's Cipher.getInstance("AES/CFB8/NoPadding") | |||
auto dec = new CFB_Mode<AES>::Decryption(aes_key, sizeof(aes_key), iv, 1); | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] |