crypto++ Sending IV to another Function but i get an error: StreamTransformationFilter: invalid PKCS #7 block padding found
crypto++ Sending IV to another Function but i get an error: StreamTransformationFilter: invalid PKCS #7 block padding found
测试程序使用 crypto++ 加密,然后它发送 iv 和消息作为 IV::EncryptedMessage。
我能够加密,但在解密时出现填充错误 #7,我已经搜索了几个小时,但无论如何都找不到将 std::string IV 传递给 crypto++。
我认为我的错误出在 decc
函数中,我在其中使用了 hexdecode?
string encc(string plain) {
using namespace CryptoPP;
AutoSeededRandomPool prng;
SecByteBlock iv(AES::BLOCKSIZE);
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
prng.GenerateBlock(iv, iv.size());
std::string cipher, recovered;
try
{
CBC_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
}
catch (const Exception& e)
{
exit(1);
}
string ciphertxt, ivString;
HexEncoder encoder(new FileSink(std::cout));
encoder.Detach(new StringSink(ivString));
encoder.Put(iv, iv.size());
encoder.MessageEnd();
encoder.Detach(new StringSink(ciphertxt));
encoder.Put((const byte*)&cipher[0], cipher.size());
encoder.MessageEnd();
string toSend = ivString + "::" + ciphertxt;
return toSend;
}
string decc(string toDec) {
using namespace CryptoPP;
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
std::string recovered;
string str1 = "::";
size_t found = toDec.find(str1);
if (found != string::npos) {
std::string sIv = toDec.substr(0, found);
std::string encMessage = toDec.substr(found + 2, toDec.length());
cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessage << endl;
string iv;
HexDecoder decoder;
decoder.Attach(new StringSink(iv));
decoder.Put((byte*)sIv.data(), sIv.size());
decoder.MessageEnd();
try
{
CBC_Mode< AES >::Decryption d;
d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
StringSource s(encMessage, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
)
);
return recovered;
}
catch (const Exception& e)
{
std::cerr << e.what() << std::endl;
exit(1);
}
}
else return NULL;
}
int main(){
string hh = encc("this is encoded");
cout << hh << endl;
string gg = decc(hh);
cout << gg << endl;
return 0;
}
似乎无法为 google 使用正确的词:)
你有一个解码错误,你应该写 toDec.substr(found + 2, toDec.length() - (found + 2))
而不是 toDec.substr(found + 2, toDec.length())
,因为 .substr() 接受符号的数量,而不是结束位置。
也许还有其他错误,但这肯定会破坏解码过程,因为加密消息中存在乱码。
你也可以只使用toDec.substr(found + 2)
,即不指定计数,如果没有指定第二个参数,则子字符串一直取到字符串的末尾。
我解码了 IV 的十六进制,但从未解码实际的加密消息。我发smh后当然看到了...
这是一个 crypto++ 编码和解码函数的功能示例,适合任何正在寻找它的人。
string encc(string plain) {
using namespace CryptoPP;
AutoSeededRandomPool prng;
SecByteBlock iv(AES::BLOCKSIZE);
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
prng.GenerateBlock(iv, iv.size());
std::string cipher, recovered;
try
{
CBC_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
}
catch (const Exception& e)
{
exit(1);
}
string ciphertxt, ivString;
HexEncoder encoder(new FileSink(std::cout));
encoder.Detach(new StringSink(ivString));
encoder.Put(iv, iv.size());
encoder.MessageEnd();
encoder.Detach(new StringSink(ciphertxt));
encoder.Put((const byte*)&cipher[0], cipher.size());
encoder.MessageEnd();
string toSend = ivString + "::" + ciphertxt;
return toSend;
}
string decc(string toDec) {
using namespace CryptoPP;
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
std::string recovered;
string str1 = "::";
size_t found = toDec.find(str1);
if (found != string::npos) {
std::string sIv = toDec.substr(0, found);
std::string encMessageHex = toDec.substr(found + 2);
cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessageHex << endl;
string iv, encMessage;
HexDecoder decoder, msgDecoder;
decoder.Attach(new StringSink(iv));
decoder.Put((byte*)sIv.data(), sIv.size());
decoder.MessageEnd();
// Forgot to decode encrypted message hex. added here
decoder.Attach(new StringSink(encMessage));
decoder.Put((byte*)encMessageHex.data(), encMessageHex.size());
decoder.MessageEnd();
try
{
CBC_Mode< AES >::Decryption d;
d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
StringSource s(encMessage, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
)
);
return recovered;
}
catch (const Exception& e)
{
std::cerr << e.what() << std::endl;
exit(1);
}
}
else return NULL;
}
int main(){
string hh = encc("this is encoded");
cout << hh << endl;
string gg = decc(hh);
cout << gg << endl;
return 0;
}
测试程序使用 crypto++ 加密,然后它发送 iv 和消息作为 IV::EncryptedMessage。
我能够加密,但在解密时出现填充错误 #7,我已经搜索了几个小时,但无论如何都找不到将 std::string IV 传递给 crypto++。
我认为我的错误出在 decc
函数中,我在其中使用了 hexdecode?
string encc(string plain) {
using namespace CryptoPP;
AutoSeededRandomPool prng;
SecByteBlock iv(AES::BLOCKSIZE);
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
prng.GenerateBlock(iv, iv.size());
std::string cipher, recovered;
try
{
CBC_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
}
catch (const Exception& e)
{
exit(1);
}
string ciphertxt, ivString;
HexEncoder encoder(new FileSink(std::cout));
encoder.Detach(new StringSink(ivString));
encoder.Put(iv, iv.size());
encoder.MessageEnd();
encoder.Detach(new StringSink(ciphertxt));
encoder.Put((const byte*)&cipher[0], cipher.size());
encoder.MessageEnd();
string toSend = ivString + "::" + ciphertxt;
return toSend;
}
string decc(string toDec) {
using namespace CryptoPP;
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
std::string recovered;
string str1 = "::";
size_t found = toDec.find(str1);
if (found != string::npos) {
std::string sIv = toDec.substr(0, found);
std::string encMessage = toDec.substr(found + 2, toDec.length());
cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessage << endl;
string iv;
HexDecoder decoder;
decoder.Attach(new StringSink(iv));
decoder.Put((byte*)sIv.data(), sIv.size());
decoder.MessageEnd();
try
{
CBC_Mode< AES >::Decryption d;
d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
StringSource s(encMessage, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
)
);
return recovered;
}
catch (const Exception& e)
{
std::cerr << e.what() << std::endl;
exit(1);
}
}
else return NULL;
}
int main(){
string hh = encc("this is encoded");
cout << hh << endl;
string gg = decc(hh);
cout << gg << endl;
return 0;
}
似乎无法为 google 使用正确的词:)
你有一个解码错误,你应该写 toDec.substr(found + 2, toDec.length() - (found + 2))
而不是 toDec.substr(found + 2, toDec.length())
,因为 .substr() 接受符号的数量,而不是结束位置。
也许还有其他错误,但这肯定会破坏解码过程,因为加密消息中存在乱码。
你也可以只使用toDec.substr(found + 2)
,即不指定计数,如果没有指定第二个参数,则子字符串一直取到字符串的末尾。
我解码了 IV 的十六进制,但从未解码实际的加密消息。我发smh后当然看到了...
这是一个 crypto++ 编码和解码函数的功能示例,适合任何正在寻找它的人。
string encc(string plain) {
using namespace CryptoPP;
AutoSeededRandomPool prng;
SecByteBlock iv(AES::BLOCKSIZE);
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
prng.GenerateBlock(iv, iv.size());
std::string cipher, recovered;
try
{
CBC_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
StringSource s(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
)
);
}
catch (const Exception& e)
{
exit(1);
}
string ciphertxt, ivString;
HexEncoder encoder(new FileSink(std::cout));
encoder.Detach(new StringSink(ivString));
encoder.Put(iv, iv.size());
encoder.MessageEnd();
encoder.Detach(new StringSink(ciphertxt));
encoder.Put((const byte*)&cipher[0], cipher.size());
encoder.MessageEnd();
string toSend = ivString + "::" + ciphertxt;
return toSend;
}
string decc(string toDec) {
using namespace CryptoPP;
std::string sKey = "UltraSecretKeyPhrase";
SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
std::string recovered;
string str1 = "::";
size_t found = toDec.find(str1);
if (found != string::npos) {
std::string sIv = toDec.substr(0, found);
std::string encMessageHex = toDec.substr(found + 2);
cout << endl << "IV: " << sIv << endl << "Encoded Msg: " << encMessageHex << endl;
string iv, encMessage;
HexDecoder decoder, msgDecoder;
decoder.Attach(new StringSink(iv));
decoder.Put((byte*)sIv.data(), sIv.size());
decoder.MessageEnd();
// Forgot to decode encrypted message hex. added here
decoder.Attach(new StringSink(encMessage));
decoder.Put((byte*)encMessageHex.data(), encMessageHex.size());
decoder.MessageEnd();
try
{
CBC_Mode< AES >::Decryption d;
d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
StringSource s(encMessage, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
)
);
return recovered;
}
catch (const Exception& e)
{
std::cerr << e.what() << std::endl;
exit(1);
}
}
else return NULL;
}
int main(){
string hh = encc("this is encoded");
cout << hh << endl;
string gg = decc(hh);
cout << gg << endl;
return 0;
}