C++ openssl 解密用一些不可读的字符替换数据的开头

问题描述 投票:0回答:1

当我尝试使用 python Crypto.Cipher aes 和 php openssl 解密一些数据(在 C++ 中使用 openssl 加密 - 下面的代码)时,出现了相同的错误 - 字符串的开头被替换为随机二进制字符,如下所示:

{"pass":"azertyu","opt":...

替换为:

"Ž{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);

}
python c++ encryption openssl
1个回答
0
投票

如评论中所示,IV 发生了变化。数据只是被最后一个块的密文替换,这是在对下一个块进行块加密之前改变明文的向量。请参阅 CBC 上的维基百科页面了解更多信息。

现在您可能会问为什么要更改 IV,因为这并不能保护用户免受您遇到的问题的影响。但是,请记住,如果您使用

AES_

 功能,您使用的是 AES 的低级软件实现。

如文档中

所示:

这些函数为 AES 对称提供了低级接口 密码算法,也称为 Rijndael。出于灵活性的考虑, 建议应用程序使用所描述的高级接口 在
EVP_EncryptInit(3)

EVP_aes_128_cbc(3) 只要有可能就可以。

所以我根本不认为 C++ 可以接受;应避免使用这些低级函数
除非

非常具体的使用它们的要求。

© www.soinside.com 2019 - 2024. All rights reserved.