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

ryoqjall  于 9个月前  发布在  Python
关注(0)|答案(1)|浏览(109)

当我试图使用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);

}

js4nwp54

js4nwp541#

正如注解中所指出的,IV发生了变化。数据只是被最后一个块的密文所取代,这是在对下一个块进行块加密之前修改明文的 * 向量。请参阅CBC上的维基百科页面以了解更多信息。
现在你可能会问为什么要改变IV,因为这并不能保护用户免受你遇到的问题的影响。但是,请记住,如果你使用AES_功能,你使用的是AES的低级软件实现。
in the documentation所示:
这些函数为AES对称密码算法(也称为Rijndael)提供了一个低级接口。出于灵活性的原因,建议应用程序尽可能使用EVP_EncryptInit(3)EVP_aes_128_cbc(3)中描述的高级接口。
所以我觉得C++根本不能接受;这些低级函数应该避免 *,除非 * 有 * 非常具体的 * 要求使用它们。

相关问题