Rust : AES算法加密、解密

时间:2024-05-18 21:56:46

Aes算法是现在使用普遍的对称性加密的算法。对于一个字符串,或相关的文件,它是如何加密,如何解密的,通过代码,可以进行很好的复现,也便于增进对加密与解密的了解。

一、从一个字符串说起

extern crate crypto;
extern crate rand;
use crypto::buffer::{BufferResult, ReadBuffer, WriteBuffer};
use crypto::{aes, blockmodes, buffer, symmetriccipher};
use std::{thread, time};

use rand::RngCore;
use rand::{OsRng, Rng};
use std::str;
fn encrypt(
    data: &[u8],
    key: &[u8],
    iv: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut encryptor =
        aes::cbc_encryptor(aes::KeySize::KeySize256, key, iv, blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true));

        final_result.extend(
            write_buffer
                .take_read_buffer()
                .take_remaining()
                .iter()
                .map(|&i| i),
        );

        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }

    Ok(final_result)
}

fn decrypt(
    encrypted_data: &[u8],
    key: &[u8],
    iv: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor =
        aes::cbc_decryptor(aes::KeySize::KeySize256, key, iv, blockmodes::PkcsPadding);

    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        final_result.extend(
            write_buffer
                .take_read_buffer()
                .take_remaining()
                .iter()
                .map(|&i| i),
        );
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }

    Ok(final_result)
}
fn main() {
    let sleep_seconds = time::Duration::from_secs(1000);
    let message = "I love Rust,Julia & Python, they are so cool! ";

    let mut key: [u8; 32] = [0; 32];
    let mut iv: [u8; 16] = [0; 16];

    let mut rng = OsRng::new().ok().unwrap();
    rng.fill_bytes(&mut key);
    rng.fill_bytes(&mut iv);
    println!("key:{:?}", key);
    println!("iv:{:?}", iv);

    let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap();
    let message_bytes = message.as_bytes();
    println!(
        "message->as_bytes:{:?}, byte_len:{}",
        message_bytes,
        message_bytes.len()
    );
    println!(
        "message->encrypted:{:?} byte_len:{}",
        encrypted_data,
        encrypted_data.len()
    );

    let decrypted_data = decrypt(&encrypted_data[..], &key, &iv).ok().unwrap();

    let the_string = str::from_utf8(&decrypted_data).expect("not UTF-8");

    assert!(message_bytes == &decrypted_data[..]);

    assert!(message == the_string);

    println!("the_string:{:?}", the_string);

    thread::sleep(sleep_seconds);
}

输出结果:
Rust : AES算法加密、解密
可以看到,不管是解密的字节数组还是字符串比对,解密都是正确的。

二、加密及解密的过程

从上面我们看出,加密的过程,比如,字符串首先是转化是字节向量(数组),然后,加密成新的字节向量(数组),加密后的向量的长度与原字节向量是大概率是不相同的。另外,也无法解析成另一个字符串。

如果是一个文件,或一个文件夹呢,或压缩的文件,原理也是一样。