Crypto++:在 Python 中加密,在 C++ 中解密
我正在尝试做以下事情:在一个Python脚本中,我使用pycrypto库来加密一些文本。然后我把它保存到文件里。接着,我加载这个文件,并使用在Python中用的同一个密钥来解码加密的文本。但是在执行stfDecryptor.MessageEnd();时出错,错误信息是:
"CryptoCPP::InvalidCiphertext at memory location [某个内存地址]"
这是我的代码:
Python:
from Crypto.Cipher import AES
BLOCK_SIZE = 16
PADDING = '{'
# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: c.encrypt(pad(s))
secret = 'MyKey123456789ab'
# create a cipher object using the random secret
cipher = AES.new(secret)
# encode a string
encoded = EncodeAES(cipher, textIn)
#save to file
fileOut = open("enc_shader.vert","w")
fileOut.write(encoded)
fileOut.close()
CPP :
std::string key = "MyKey123456789ab";
std::string iv = "aaaaaaaaaaaaaaaa";
std::ifstream fileIn("enc_shader.vert");
std::stringstream buffer;
buffer << fileIn.rdbuf();
std::string ciphertext1 = buffer.str();
CryptoPP::AES::Decryption aesDecryption((byte*)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, (byte*)iv.c_str() );
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext1.c_str() ), ciphertext1.size() );
stfDecryptor.MessageEnd();//fails here.
根据我所了解,这两个端点应该可以正常工作,因为pycrypto只是CryptoCPP库的一个封装。也许我在CPP那边漏掉了填充的步骤?
更新:
好的,我发现更改填充方案:
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) ,BlockPaddingSchemeDef::NO_PADDING);
可以在CPP那边解码字符串。但是解码后的字符串包含了填充字符。比如说,如果原始字符串是"aaaaaaaaaaaaaaaaa"
解码后的字符串看起来像这样:
"aaaaaaaaaaaaaaaaa{{{{{{{{{{{{{{{"
这里添加了15个字节来填充到32个字节。
为什么Crypto++在解密时不去掉这些填充字符呢?
1 个回答
3
你的Python加密代码是手动添加'{'字符来填充到块大小。这种填充方式并不是标准的填充模式,所以Crypto++的代码无法通过内置的填充方案来去掉这些填充字符。换句话说,你应该使用NO_PADDING
来解密,然后自己去掉填充。
不过,最好是让Python代码使用PKCS#7填充,这样你就可以在Crypto++中使用PKCS_PADDING
作为选项。