Rust Decrypt from Python cryptography

Question:

I used cryptography to encrypt image file in Python. The code is here:

import hashlib
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import time

key = "secretkey"
keyBytes = hashlib.sha256(key.encode()).digest()

ivBytes = b"xdaxe4x87xa7ix8arbOCxbd x02xbc*["

file_name = "1024.jpg"

with open(file_name, "rb") as f:
    imageBytes = f.read()

cipher = Cipher(algorithms.AES(keyBytes), modes.CBC(ivBytes), backend=default_backend())

encryptor = cipher.encryptor()
padder = padding.PKCS7(algorithms.AES.block_size).padder()
imageBytes = padder.update(imageBytes) + padder.finalize()
encryptedImageBytes = encryptor.update(imageBytes) + encryptor.finalize()

encodedImageString = base64.b64encode(encryptedImageBytes).decode()

encrpyted_file_name = "encrypted_image" + file_name
with open(encrpyted_file_name, "wb") as f:
    f.write(encryptedImageBytes)

and I got encrpyted_image1024.jpg. Now I want to decrypt this file in Rust. The code is here :

use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

use base64;
use crypto::aes::{cbc_decryptor, KeySize};
use crypto::blockmodes::NoPadding;
use crypto::buffer::{RefReadBuffer, RefWriteBuffer};

fn main() {
    let mut file = File::open("./src/encrypted_image1024.jpg").unwrap();
    let mut encrypted_image = Vec::new();
    file.read_to_end(&mut encrypted_image).unwrap();
    println!("{:?}", &encrypted_image);

    let decoded_image = base64::decode(&encrypted_image).unwrap();  // error

    let key = b"secretkey";
    let iv = b"xdaxe4x87xa7ix8arbOCxbd x02xbc*[";
    let mut decryptor = cbc_decryptor(KeySize::KeySize256, key, iv, NoPadding);
    let mut decrypted_image = Vec::<u8>::new();
    let mut read_buffer = RefReadBuffer::new(&decoded_image);
    let mut write_buffer = RefWriteBuffer::new(&mut decrypted_image);
    decryptor
        .decrypt(&mut read_buffer, &mut write_buffer, true)
        .unwrap();

    let path = Path::new("decrypted_image1024.jpg");
    let mut file = File::create(&path).unwrap();
    file.write_all(&decrypted_image).unwrap();
}

I got the error : Err` value: InvalidByte(1, 59) in base64::decode(&encrypted)_image), and I found this error occurred because the bytes of image file is not Base64.

So I printed the encrypted_image like using println!("{:?}", &encrypted_image); and the result was:

[11, 90, 193, 68, 189, 179, 37, 240, 16, 87, 141, 123, 112, 213, 173, 242, 218, 0, 219, 151, 151, 53, 30, 96, 168, 90, 105, 62, 16, 52, 152, 8, 33, 2, 158, 52, 52, 112, 113, 203, 169, 32, 251, 203, 203, 177, 242, 199, 174, 203, 198, 111, 2, 54, 96, 207, 117, 115, 12, 18, 136, 189, 11, 155, 10, 79, 252, 122, 172, 208, 124, 116, 179, 34, 52, 239, 159, 142, 218, 153, 217, 224, 210, 225, 171, 190, 163, 7, 113, 67, 165, 6, 126, 47, 101, 43, 113, 254, 30, 201, 0, 192, 121, 252, 199, 39, 112, 119, 0, 48, 58, 124, 162, 124, 77, 115, 134, 40, 19, 172, 171, 165, 167, 14, 77, 155, 138, 48, 71, 157, 65, 146, 84, 130, 95, 79, 58, 45, 198, 164, 141, 249, 119, 25, 240, 149, 72, 129, 194, 31, 234] // it's too long, so I shortened..

In this situation, do I need to change using base64 encoding in Python code? Or Is there any way to decrpyt this kind of bytes in Rust?
Many thanks 🙂

Asked By: Youdi

||

Answers:

Thanks for @freaskish, I changed my Python code not using base64 encoding, and write encryptedImageBytes. Here’s my Python code :

import hashlib
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import time

key = "oingisprettyintheworld1234567890"
keyBytes = hashlib.sha256(key.encode()).digest()

ivBytes = b"xdaxe4x87xa7ix8arbOCxbd x02xbc*["

file_name = "1024.jpg"

with open(file_name, "rb") as f:
    imageBytes = f.read()

cipher = Cipher(algorithms.AES(keyBytes), modes.CBC(ivBytes), backend=default_backend())

encryptor = cipher.encryptor()
padder = padding.PKCS7(algorithms.AES.block_size).padder()
imageBytes = padder.update(imageBytes) + padder.finalize()
encryptedImageBytes = encryptor.update(imageBytes) + encryptor.finalize()

encrpyted_file_name = "encrypted_image" + file_name
with open(encrpyted_file_name, "wb") as f:
    f.write(encryptedImageBytes)

and In rust, I put encrypted_image_bytes to read_buffer right away.

use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

use base64;
use crypto::aes::{cbc_decryptor, KeySize};
use crypto::blockmodes::NoPadding;
use crypto::buffer::{RefReadBuffer, RefWriteBuffer};

fn main() {
    let mut file = File::open("./src/encrypted_image1024.jpg").unwrap();
    let mut encrypted_image = Vec::new();
    let mut encrypted_image_bytes = Vec::new();
    file.read_to_end(&mut encrypted_image_bytes).unwrap();

    let key = b"oingisprettyintheworld1234567890";
    let iv = b"xdaxe4x87xa7ix8arbOCxbd x02xbc*[";
    let mut decryptor = cbc_decryptor(KeySize::KeySize256, key, iv, NoPadding);
    let length = encrypted_image_bytes.len();
    let mut decrypted_image = vec![0; length];
    let mut read_buffer = RefReadBuffer::new(&encrypted_image_bytes);
    let mut write_buffer = RefWriteBuffer::new(&mut decrypted_image);
    decryptor
        .decrypt(&mut read_buffer, &mut write_buffer, true)
        .unwrap();

    let path = Path::new("decrypted_image1024.jpg");
    let mut file = File::create(&path).unwrap();
    file.write_all(&decrypted_image).unwrap();
}

And this code didn’t get any compile error, but I coundn’t open the result, ‘decrypted_image1024.jpg’ file. I think there was something wrong in decryption..

Answered By: Youdi

Ok I gave up this problem. I thought it’s possible to encrypt in Python and decrypt in Rust, but there was something error between different languages.
Instead, I used ‘magic-crypt’ crate, both encrypted and decrypted in Rust.

Answered By: Youdi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.