Encrypt/Decrypt Large text using rust's openssl library
我正在尝试编写一个API以使用rust的openssl包装器库来加密/解密文件。
这是库:https://docs.rs/openssl/0.10.25/openssl/index.html
文档中的所有示例均展示了如何使用Padding加密短字符串。我想加密可能很长的文件。
问题是我最多只能加密密钥的长度(使用
因此,为了解决该问题,我将数据分为多个块,对每个块进行加密/解密,然后将加密/解密的块附加到结果向量中。然后,我将其写入文件并从文件读取到矢量,然后再解密。
我的工作概述:
代码在这里(当心-我将粘贴的内容复制粘贴到下面的一个块中,最初它们位于单独的模块/文件中)
我最初生成rsa密钥
1 2 3 4 5 6 7 8 | fn generate_rsa_key_pair() -> utils::Pair<Vec<u8>, Vec<u8>> { let rsa = Rsa::generate(4096).unwrap(); let public_pem = rsa.public_key_to_pem().unwrap(); let private_pem = rsa.private_key_to_pem().unwrap(); Pair::new(public_pem, private_pem) // custom data structure (basically a tuple) } |
然后,我将它们写入文件,并使用文件中的密钥进行后续运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | extern crate openssl; use openssl::pkey::{Private, Public}; use openssl::rsa::{Padding, Rsa}; use std::cmp::max; use std::io::{BufWriter, Result, Write}; use std::str; fn main() { let (public, private) = generate_rsa_from_files(); let data = read_file_into_binary_vec("./resources/example_text.txt").unwrap(); let enc_data = encrypt_data_with_pubkey(data.as_slice(), public).unwrap(); println!("{:?}", enc_data); binary_slice_to_file(enc_data.as_slice(),"./resources/example_enc.txt").unwrap(); let dec_data = decrypt_data_with_prikey(enc_data.as_slice(), private).unwrap(); println!("{}", str::from_utf8(dec_data.as_slice()).unwrap()); binary_slice_to_file(dec_data.as_slice(),"./resources/example_dec.txt").unwrap(); } fn generate_rsa_from_files() -> (Vec<u8>, Vec<u8>) { let public = read_file_into_binary_vec("./resources/public_key").unwrap(); let private = read_file_into_binary_vec("./resources/private_key").unwrap(); (public, private) } fn read_file_into_binary_vec(file_path: &str) -> Result<Vec<u8>> { std::fs::read(file_path) } fn binary_slice_to_file(data: &[u8], file_path: &str) -> Result<()> { let file = std::fs::File::create(file_path)?; let mut buf_writer = BufWriter::new(file); buf_writer.write_all(data) } fn encrypt_data_with_pubkey(data: &[u8], pub_key: Vec<u8>) -> Result<Vec<u8>> { let data_len = data.len(); let public_rsa: Rsa<Public> = Rsa::public_key_from_pem(pub_key.as_slice())?; let buf_len = public_rsa.size() as usize; let mut buffer: Vec<u8> = vec![0; buf_len]; let mut encrypted_data: Vec<u8> = Vec::with_capacity(max(data_len, buf_len)); println!("{}", public_rsa.size()); for chunk in data.chunks(buf_len) { println!("Encrypting (len = {}): {:?}", chunk.len(), chunk); let chunk_mod; if chunk.len() < buf_len { chunk_mod = pad_chunk_to_size(chunk, buf_len); } else { chunk_mod = Vec::from(chunk); } let chunk_mod = chunk_mod.as_slice(); println!("Encrypting (len = {}): {:?}", chunk_mod.len(), chunk_mod); let enc_len = public_rsa .public_encrypt(chunk_mod, buffer.as_mut_slice(), Padding::NONE) .expect("Error Encrypting"); println!("Enc Data Len : {}", enc_len); encrypted_data.extend_from_slice(buffer.as_slice()); } Ok(encrypted_data) } fn decrypt_data_with_prikey(enc_data: &[u8], priv_key: Vec<u8>) -> Result<Vec<u8>> { let data_len = enc_data.len(); let private_rsa: Rsa<Private> = Rsa::private_key_from_pem(priv_key.as_slice())?; let buf_len = private_rsa.size() as usize; let mut buffer: Vec<u8> = vec![0; buf_len]; let mut decrypted_data: Vec<u8> = vec![0; data_len]; println!("{}", private_rsa.size()); for chunk in enc_data.chunks(buf_len) { private_rsa.private_decrypt(chunk, &mut buffer, Padding::NONE).expect("Error Decrypting");; decrypted_data.extend_from_slice(buffer.as_slice()); } Ok(decrypted_data) } fn pad_chunk_to_size(chunk: &[u8], desired_size: usize) -> Vec<u8> { let mut resized_vec = Vec::with_capacity(desired_size); for &element in chunk { resized_vec.push(element); } while resized_vec.len() < desired_size { resized_vec.push(0); } println!( "Desired Length = {}, Actual Length = {}", desired_size, resized_vec.len() ); resized_vec } |
我面临的问题是,在我的文件中,我在解密文件的开头和结尾发现了许多奇怪的字符。来自vim的图像如下所示。
我似乎无法弄清楚如何消除这些字符(最终会增加文件大小),如果我选择使用填充,我将如何去做。
编辑:我应该注意,如果我将输出打印到终端,则看不到那些字符,但是它们肯定存在于文件中。
任何帮助表示赞赏。
这些字符是
-
开头的内容来自您的
decrypt_data_with_prikey 函数。该功能:-
用
data_len 零初始化其输出矢量; -
然后将解密的数据附加到此向量。初始零永远不会删除也不会被覆盖。将
let mut decrypted_data: Vec 替换为= vec![0; data_len] let mut decrypted_data = Vec::new() ,以空向量开头;如果要为数据预分配内存,则将let mut decrypted_data = Vec::with_capacity (data_len) 替换为let mut decrypted_data = Vec::with_capacity (data_len) 。
-
用
- 最后的那些来自您在加密期间添加的填充。您将需要以某种方式传达从加密功能添加到解密功能的填充量,以便可以将解密后的数据截断为适当的长度。
作为一点无关的说明,当使用公共/私有密钥对加密数据时,通常建议:
- 创建一个随机对称密钥;
- 用公共密钥加密该对称密钥;
- 用对称密钥加密数据;
- 在头中添加加密的对称密钥,以便接收者可以知道它。
这种方法有两个优点:
- 由于对称密码比非对称密码快得多,因此提高了速度。
- 由于它泄漏的非对称密钥对信息较少,因此提高了安全性,因此即使攻击者设法解密消息,她也将无法解密使用同一密钥对的其他消息。