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 🙂
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..
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.
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 🙂
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..
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.