使用 Crypto++ 解密格式正确的密文时遇到问题
Having trouble decrypting a well-formed cipher text using Crypto++
背景
我已经花了大约一天的时间来解密一个看似格式正确的密文。假设我们有以下十六进制编码的密文,其中恰好包含 160 个字符,因此有 80 个字节。
QString c = "1BFAC407AF0D440A2D6176C0B5D125AA96088490299AC18C74623C0EF1BB1372E554FC4150A8066220E943697BE2491D8AE13AA036B298425AC510A8A917D59EBB69708B9040AB3A84C63043EAD4AB07";
QString k = CryptoUtils::hexEncode("abc");
QString p = CryptoUtils::decrypt(c, k);
qDebug() << p;
假设我们使用的是 AES 256,AFAIK,密钥长度必须为 32 字节,密文长度必须为 16 字节的倍数,关于我的代码段,所有这些条件都得到满足。
请注意,我使用带有密码短语的 SHA256 来生成 32 字节的密钥。因此,这确保所有密钥的长度都是 32 字节。
Full source codes 这些功能可以在我的 GitHub(在分支 Part1)的回购协议中找到。
我的问题
当我想要 运行 这段代码时,我的应用程序崩溃了。这是例外情况:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
The program has unexpectedly finished.
我搜索了一下这个问题,发现这可能是因为加密纯文本后尾随 [=12=]
。但是,我不能只解决问题。请帮助我,这让我发疯。
Full source codes of those function can be found on my repo on GitHub
我至少会进行以下更改:
QString CryptoUtils::encrypt(QString text, QString keyhex)
{
...
// name the variable, kill the memory leak
SHA256 sha256;
StringSource ss1(decodedKey, size, true, new HashFilter(sha256, new ArraySink(key, AES::MAX_KEYLENGTH)));
...
// name the variable
StringSource ss2(plain, true, new StreamTransformationFilter(Encryptor, new HexEncoder(new StringSink(encrypted))));
// verify embedded NULLs don't affect results
QString qs = QString::fromStdString(encrypted);
assert(qs.length() == encrypted.length());
}
并且:
QString CryptoUtils::decrypt(QString text, QString keyhex)
{
// bad karma here...
string encrypted = text.toStdString();
assert(encrypted.length() == text.length());
...
// name the variable, kill the memory leak
SHA256 sha256;
StringSource ss1(decodedKey, size, true, new HashFilter(sha256, new ArraySink(key, AES::MAX_KEYLENGTH)));
...
// name the variable,
StringSource ss2(encrypted, true, new HexDecoder(new StreamTransformationFilter(Decryptor, new StringSink(plain))));
// verify embedded NULLs don't affect results
QString qs = QString::fromStdString(plain);
assert(qs.length() == plain.length());
}
hexEncode
函数似乎有问题:
QString CryptoUtils::hexEncode(QString text)
{
byte *bytearray = (byte *) text.toLatin1().data();
int length = text.toLatin1().length();
return hexEncode(bytearray, length);
}
应替换为:
QString CryptoUtils::hexEncode(QString text)
{
byte *bytearray = (byte *) text.toStdString().data();
int length = text.length();
return hexEncode(bytearray, length);
}
背景
我已经花了大约一天的时间来解密一个看似格式正确的密文。假设我们有以下十六进制编码的密文,其中恰好包含 160 个字符,因此有 80 个字节。
QString c = "1BFAC407AF0D440A2D6176C0B5D125AA96088490299AC18C74623C0EF1BB1372E554FC4150A8066220E943697BE2491D8AE13AA036B298425AC510A8A917D59EBB69708B9040AB3A84C63043EAD4AB07";
QString k = CryptoUtils::hexEncode("abc");
QString p = CryptoUtils::decrypt(c, k);
qDebug() << p;
假设我们使用的是 AES 256,AFAIK,密钥长度必须为 32 字节,密文长度必须为 16 字节的倍数,关于我的代码段,所有这些条件都得到满足。
请注意,我使用带有密码短语的 SHA256 来生成 32 字节的密钥。因此,这确保所有密钥的长度都是 32 字节。
Full source codes 这些功能可以在我的 GitHub(在分支 Part1)的回购协议中找到。
我的问题
当我想要 运行 这段代码时,我的应用程序崩溃了。这是例外情况:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
The program has unexpectedly finished.
我搜索了一下这个问题,发现这可能是因为加密纯文本后尾随 [=12=]
。但是,我不能只解决问题。请帮助我,这让我发疯。
Full source codes of those function can be found on my repo on GitHub
我至少会进行以下更改:
QString CryptoUtils::encrypt(QString text, QString keyhex)
{
...
// name the variable, kill the memory leak
SHA256 sha256;
StringSource ss1(decodedKey, size, true, new HashFilter(sha256, new ArraySink(key, AES::MAX_KEYLENGTH)));
...
// name the variable
StringSource ss2(plain, true, new StreamTransformationFilter(Encryptor, new HexEncoder(new StringSink(encrypted))));
// verify embedded NULLs don't affect results
QString qs = QString::fromStdString(encrypted);
assert(qs.length() == encrypted.length());
}
并且:
QString CryptoUtils::decrypt(QString text, QString keyhex)
{
// bad karma here...
string encrypted = text.toStdString();
assert(encrypted.length() == text.length());
...
// name the variable, kill the memory leak
SHA256 sha256;
StringSource ss1(decodedKey, size, true, new HashFilter(sha256, new ArraySink(key, AES::MAX_KEYLENGTH)));
...
// name the variable,
StringSource ss2(encrypted, true, new HexDecoder(new StreamTransformationFilter(Decryptor, new StringSink(plain))));
// verify embedded NULLs don't affect results
QString qs = QString::fromStdString(plain);
assert(qs.length() == plain.length());
}
hexEncode
函数似乎有问题:
QString CryptoUtils::hexEncode(QString text)
{
byte *bytearray = (byte *) text.toLatin1().data();
int length = text.toLatin1().length();
return hexEncode(bytearray, length);
}
应替换为:
QString CryptoUtils::hexEncode(QString text)
{
byte *bytearray = (byte *) text.toStdString().data();
int length = text.length();
return hexEncode(bytearray, length);
}