Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用CryptoPP库加密和解密字节数组/向量_C++_Encryption_Aes_Crypto++ - Fatal编程技术网

C++ 使用CryptoPP库加密和解密字节数组/向量

C++ 使用CryptoPP库加密和解密字节数组/向量,c++,encryption,aes,crypto++,C++,Encryption,Aes,Crypto++,我试图加密已解析为字符串的字节数组。这似乎适用于所有情况,但字节数组包含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, 0

我试图加密已解析为字符串的字节数组。这似乎适用于所有情况,但字节数组包含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;
}
intmain()
{
字节密文带零字节[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
};
字符串密文((char*)带零字节的密文);
字符串明文=解密(密文,sizeof(密文带零字节));
返回1;
}
字符串解密(字符串密文,整数大小)
{
字符串解密文本;
CryptoPP::AES::Decryption AES Decryption(密钥,CryptoPP::AES::默认密钥长度);
CryptoPP::CBC_Mode_ExternalCipher::解密cbcDecryption(AESDryption,iv);
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption,
新的CryptoPP::HexEncoder(
新的CryptoPP::StringSink(decryptedText));
stfDecryptor.Put(reinterpret_cast(cipherText.c_str()),size);
stfDecryptor.MessageEnd();
返回解密文本;
}
在本例中,字节数组包含0x00。这会导致密文缩短,导致长度无效。引发异常,声明:“StreamTransformationFilter:无效PKCS#找到7块填充”

因此我认为最好使用ArraySourceArraySink来确保字符串不是以零结尾的

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;
}
intmain()
{
字节密文带零字节[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
};
向量cipherTextData(cipherTextWithZeroByte,cipherTextWithZeroByte+sizeof(cipherTextWithZeroByte)/sizeof(cipherTextWithZeroByte[0]);
向量明文数据=解密(密文数据);
返回1;
}
矢量解密(矢量密文)
{
矢量明文;
plainText.resize(cipherText.size());
CryptoPP::CBC_模式::解密解密器;
解密器.SetKeyWithIV(key,sizeof(key),iv,sizeof(iv));
CryptoPP::ArraySource ss(&cipherText[0]),cipherText.size(),true,
新的CryptoPP::HexEncoder(
新的CryptoPP::StreamTransformationFilter(解密程序,
新的CryptoPP::ArraySink(plainText.data(),plainText.size());
返回纯文本;
}
在这种情况下,将引发一个异常,即密文不是密钥长度的倍数,这里显然不是这种情况。(密钥=16字节,密文=16字节)。我认为库将字节数组强制转换为一个字符串,而不包含0x00字节之后的所有数据


我做错了什么?

加密是一个二进制字节而不是字符操作。因此,加密输出不能转换为字符串。如果需要字符串输出,请将加密数据编码为与字符串兼容的格式。常用格式为Base64和十六进制

特别是,按照“C”类语言的约定,字符串中的空字节表示字符串的结尾


即在加密时,将二进制数据编码为字符串格式,在解密时,首先使用编码操作的逆运算将字符串表示解码为二进制数据

“我认为库将字节数组强制转换为一个字符串,而忽略了0x00字节之后的所有数据…”不,这不会发生。始终使用字符串的
size
成员函数。你的问题在别处。“出现了一个异常,密文不是密钥长度的倍数…”-这里听起来有些不对劲。我不认识这个信息。实际的例外情况是什么?听起来又是一条无效的填充消息(有点)。可能您的文件已过期,需要在更改后重新生成。在第二个示例中,您需要将
纯文本
调整为恢复邮件的实际大小,然后再执行
返回纯文本
。您可能需要调用
ArraySink
成员函数
TotalPutLength
,以获取恢复的消息大小。Crypto++wiki上提供了一个示例。