当我试图使用python Crypto.Cipher aes和php openssl解密一些数据(在c++中使用openssl加密-代码如下)时,出现了相同的错误-字符串的开头被替换为随机的二进制字符,如下所示:
第一个月
替换为:"Ž{mÂ┬X▒ Íł.Q>4","opt":...
个
这可能是一些问题与填充,但我不能弄清楚。
要解密的Python代码:
def decrypt(ciphertext_hex):
key = b"t*H3_B3$t/k$%evr"
data = binascii.unhexlify(ciphertext_hex)
iv = data[:AES.block_size]
data = data[AES.block_size:]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(data), AES.block_size)
print(decrypted)
# return decrypted.decode("utf-8", errors="replace")
return decrypted.decode("utf-8")
字符串
加密的C++代码:
std::string binToHex(const std::string &input)
{
std::ostringstream hexStream;
hexStream << std::hex << std::setfill('0');
for (unsigned char c : input)
{
hexStream << std::setw(2) << static_cast<int>(c);
}
return hexStream.str();
}
std::string crypt(const std::string &data, const std::string &key)
{
const unsigned char *keyBytes = reinterpret_cast<const unsigned char *>(key.c_str());
const unsigned char *dataBytes = reinterpret_cast<const unsigned char *>(data.c_str());
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
AES_KEY aesKey;
if (AES_set_encrypt_key(keyBytes, 128, &aesKey) < 0) {
std::cout << "key";
return "";
}
unsigned char iv[AES_BLOCK_SIZE];
if (RAND_bytes(iv, AES_BLOCK_SIZE) != 1)
{
std::cout << "rand bytes";
return "";
}
size_t paddedLen = (data.length() + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
unsigned char *paddedData = new unsigned char[paddedLen];
std::memcpy(paddedData, dataBytes, data.length());
memset(paddedData + data.length(), paddedLen - data.length(), paddedLen - data.length());
unsigned char ciphertext[paddedLen];
AES_cbc_encrypt(paddedData, ciphertext, paddedLen, &aesKey, iv, AES_ENCRYPT);
std::string output(reinterpret_cast<char *>(iv), AES_BLOCK_SIZE);
output.append(reinterpret_cast<char *>(ciphertext), paddedLen);
delete[] paddedData;
return binToHex(output);
}
型
1条答案
按热度按时间js4nwp541#
正如注解中所指出的,IV发生了变化。数据只是被最后一个块的密文所取代,这是在对下一个块进行块加密之前修改明文的 * 向量。请参阅CBC上的维基百科页面以了解更多信息。
现在你可能会问为什么要改变IV,因为这并不能保护用户免受你遇到的问题的影响。但是,请记住,如果你使用
AES_
功能,你使用的是AES的低级软件实现。如in the documentation所示:
这些函数为AES对称密码算法(也称为Rijndael)提供了一个低级接口。出于灵活性的原因,建议应用程序尽可能使用EVP_EncryptInit(3)和EVP_aes_128_cbc(3)中描述的高级接口。
所以我觉得C++根本不能接受;这些低级函数应该避免 *,除非 * 有 * 非常具体的 * 要求使用它们。