【发布时间】:2017-12-13 11:10:12
【问题描述】:
我正在尝试加密已解析为字符串的字节数组。这似乎适用于所有情况,除了字节数组包含 0x00 的情况。
int main()
{
byte cipherTextWithZeroByte[32] = {
0xD3, 0xFA, 0xD6, 0xEC, 0x84, 0x4E, 0xD3, 0xD8,
0x2B, 0x76, 0x6C, 0xE8, 0x02, 0xF2, 0xB2, 0x6F,
0x00, 0xE8, 0x99, 0x8C, 0xEC, 0x4B, 0x3C, 0x7D,
0xAC, 0xDE, 0x86, 0x02, 0x51, 0xAB, 0x3F, 0x04
};
string cipherText((char *)cipherTextWithZeroByte);
string plainText = decrypt(cipherText, sizeof(cipherTextWithZeroByte));
return 1;
}
string decrypt(string cipherText, int size)
{
string decryptedText;
CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv);
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption,
new CryptoPP::HexEncoder(
new CryptoPP::StringSink(decryptedText)));
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(cipherText.c_str()), size);
stfDecryptor.MessageEnd();
return decryptedText;
}
在这种情况下,字节数组包含 0x00。这会导致密文被缩短,导致长度无效。抛出异常说明:'StreamTransformationFilter: invalid PKCS #7 block padding found'
所以我认为最好使用 ArraySource 和 ArraySink 来确保字符串不以零结尾。
int main()
{
byte cipherTextWithZeroByte[32] = {
0xD3, 0xFA, 0xD6, 0xEC, 0x84, 0x4E, 0xD3, 0xD8,
0x2B, 0x76, 0x6C, 0xE8, 0x02, 0xF2, 0xB2, 0x6F,
0x00, 0xE8, 0x99, 0x8C, 0xEC, 0x4B, 0x3C, 0x7D,
0xAC, 0xDE, 0x86, 0x02, 0x51, 0xAB, 0x3F, 0x04
};
vector<byte> cipherTextData(cipherTextWithZeroByte, cipherTextWithZeroByte + sizeof(cipherTextWithZeroByte) / sizeof(cipherTextWithZeroByte[0]));
vector<byte> plainTextData = decrypt(cipherTextData);
return 1;
}
vector<byte> decrypt(vector<byte> cipherText)
{
vector<byte> plainText;
plainText.resize(cipherText.size());
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor;
decryptor.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
CryptoPP::ArraySource ss(&cipherText[0], cipherText.size(), true,
new CryptoPP::HexEncoder(
new CryptoPP::StreamTransformationFilter(decryptor,
new CryptoPP::ArraySink(plainText.data(), plainText.size()))));
return plainText;
}
在这种情况下,会抛出密文不是密钥长度的倍数的异常,这显然不是这里的情况。 (密钥 = 16 字节,密文 = 16 字节)。我认为该库将字节数组转换为字符串,省略了 0x00 字节之后的所有数据。
我做错了什么?
【问题讨论】:
-
“我认为库将字节数组转换为字符串,忽略了 0x00 字节之后的所有数据......” - 不,这不会发生。始终使用字符串的
size成员函数。你的问题出在其他地方。 -
“抛出一个异常,密文不是密钥长度的倍数...” - 这里听起来不太对劲。我不认识这个消息。实际的例外是什么?听起来又像是无效的填充消息(有点)。也许您有一个过时的文件需要在更改后重建。
-
在第二个示例中,您需要在执行
return plainText之前将plainText调整为恢复邮件的实际大小。您可能需要调用ArraySink成员函数TotalPutLength来获取恢复的消息大小。 Crypto++ wiki 上的 ArraySink 提供了一个示例。
标签: c++ encryption aes crypto++