Crypto ++ライブラリを使用してデータを暗号化し、ユーザー定義のパスワードが32バイト未満の場合はどうなりますか?
パスワード派生機能(KDF)を使用してパスワードを消化します。現代のものは、Extract-then-Expandモデルを使用するKrawczykとEronenのHKDFです。論文はCryptographic Extraction and Key Derivation: The HKDF Schemeにあります。
IVにも使用することを検討する必要があります。 32バイト(AES::MAX_KEYLENGTH
)を導出するのではなく、代わりに48バイト(AES::MAX_KEYLENGTH+AES::BLOCKSIZE
)を派生させます。デザイン内のIVは、KDFのパラメータsalt
に使用できます。
たぶんのようなもの:
#include <iostream>
#include <string>
using namespace std;
#include "cryptlib.h"
#include "aes.h"
#include "sha.h"
#include "hkdf.h"
#include "modes.h"
#include "filters.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
SecByteBlock key(AES::MAX_KEYLENGTH+AES::BLOCKSIZE);
string password("passwordFromUser"), iv("<random value>"), message("encryptMe");
string encrypted, recovered;
try
{
HKDF<SHA256> hkdf;
hkdf.DeriveKey(key, key.size(), (const byte*)password.data(), password.size(), (const byte*)iv.data(), iv.size(), NULL, 0);
///////////////////////////////////////////////////////////////////////
CTR_Mode<AES>::Encryption encryption;
encryption.SetKeyWithIV(key, AES::MAX_KEYLENGTH, key+AES::MAX_KEYLENGTH);
StringSource encryptor(message, true,
new StreamTransformationFilter(encryption,
new StringSink(encrypted))
);
///////////////////////////////////////////////////////////////////////
CTR_Mode<AES>::Decryption decryption;
decryption.SetKeyWithIV(key, AES::MAX_KEYLENGTH, key+AES::MAX_KEYLENGTH);
StringSource decryptor(encrypted, true,
new StreamTransformationFilter(decryption,
new StringSink(recovered))
);
cout << "Message: " << message << endl;
cout << "Recovered: " << recovered << endl;
}
catch(const Exception& ex)
{
cerr << ex.what() << endl;
return 1;
}
return 0;
}
上記の暗号化方式を使用している場合、あなたは{iv,message}
ペアを追跡する必要があります。 IVは、パスワードが効果的にAESキーを修正するため、メッセージごとの一意性を保証するために必要です。
何ユーザーは、その後長い32バイトであるパスワードを選択した場合?私の場合、パスワードは切り捨てられてしまいますが、それは私には正しいとは言えません。
KDFがそれを処理します。エントロピーは、どれほどか、どれくらいかにかかわらず抽出されます。
StringSource encryptor(textToEncrypt, true,
new StreamTransformationFilter(encryption,
new StringSink(verschluesselterText),
StreamTransformationFilter::NO_PADDING
)
パディングモードを指定する必要はありません。 BlockPaddingSchemeのドキュメントも参照してください。
CTRなどのモードには注意が必要です。 CTRモードxorはプレーンテキストのキーストリームです。誰かが別のメッセージでパスワードを再利用すると、キーストリームを回復して平文回復につながる可能性があります。
ivText
が各メッセージに固有の場合は、メッセージごとに一意のキーストリームを確保するためにKDFに追加する必要があります。 IVをHKDFのsalt
パラメータとして追加します。ここで「ユニーク」は、メッセージ「」が「Hello World」の場合、メッセージを暗号化するたびにIVが異なることを意味します。
IVはまさに "Iv16BytesOfText ..."(つまりその固定)ですが、それに固有のものは何もありません。ユーザーのパスワードからさらに16バイトを派生させるだけです。その後、キーストロークxor攻撃を避けるために、CBCのようなモードに切り替えます。
最後に、おそらくCCM、EAX、またはGCMモードを使用する必要があります。今、あなたは秘密を持っています。通常、真偽も欲しい。信頼性を得るために、多くの場合、Authenticated Encryptionモードを選択します。
この問題をどのように解決しましたか? – jww