Python AES 256-CBC,使用Rust OpenSSL解密

xxls0lw8  于 2023-02-28  发布在  Python
关注(0)|答案(1)|浏览(158)

我使用这个OpenSSL调用来加密(对称)文件

key = secrets.token_bytes(32)
iv = secrets.token_bytes(16)

encrypted_file = file_path + ".enc"
subprocess.run(
    [
        "openssl", "enc", "-aes-256-cbc",
        "-K", key.hex(),
        "-iv", iv.hex(),
        "-in", file_path,
        "-out", encrypted_file,
    ]
)

用这个 rust 码来解密。

let mut ctx = CipherCtx::new().expect("Can't build CipherCtx");
ctx.decrypt_init(Some(Cipher::aes_256_cbc()), Some(&key), Some(&iv)).unwrap();

let mut data = vec![];
archive.read_to_end(&mut data).expect("Can't read encrypted archive file");

let mut bytes = vec![];
ctx.cipher_update_vec(&data, &mut bytes).unwrap();
ctx.cipher_final_vec(&mut bytes).unwrap();

let mut decrypted_file = tempfile().expect("Can't create temporary file");
decrypted_file.write_all(&bytes).expect("Can't write decrypted archivce file to disk");

确实可以.但是我想使用Python cryptography库来加密我的文件,所以我将上面的代码块替换为

with open(file_path, "rb") as raw_file, open(encrypted_file, "wb") as enc_file:
    encryptor = Cipher(algorithms.AES256(key), modes.CBC(iv)).encryptor()
    enc_file.write(encryptor.update(raw_file.read()))
    enc_file.write(encryptor.finalize())

我认为它要求的是相同的东西(eas-256-cbc,相同的密钥/iv,但是使用字节,而不是十六进制)。

ErrorStack([Error {
    code: 101077092,
    library: "digital envelope routines",
    function: "EVP_DecryptFinal_ex",
    reason: "bad decrypt",
   file: "../crypto/evp/evp_enc.c", line: 610
}])

因为我在Rust中使用OpenSSL 1.1.1#,所以我还尝试使用cryptography v36.0.2(静态链接到OpenSSL 1.1.1n)而不是最新版本(39.0.1静态链接到OpenSSL 3.0.8),但我得到了完全相同的错误。
我需要更改什么才能让Rust解密我的文件?

lc8prwob

lc8prwob1#

正如@Topaco在上面的注解中所解释的,cryptography不会自动填充您试图加密的数据,因此您必须自己进行填充。

with open(file_path, "rb") as raw_file, open(encrypted_file, "wb") as enc_file:
    # !!! New code here !!!
    from cryptography.hazmat.primitives import padding
    padder = padding.PKCS7(algorithms.AES256.block_size).padder()
    padded_data = padder.update(raw_file.read())
    padded_data += padder.finalize()

    encryptor = ...
    enc_file.write(encryptor.update(padded_data))
    ...

这只是填充文件的字节数,以达到所需的块大小(AES 256为128),然后就可以像平常一样加密了。
填充与“模式”相关联。如CBC文档中所写:
CBC(密码块链接)是块密码的一种操作模式。它被认为是加密功能强大的模式。使用此模式时需要填充。

相关问题