Rust : AES算法加密、解密

76 篇文章 15 订阅
30 篇文章 0 订阅

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);
}

输出结果:
在这里插入图片描述
可以看到,不管是解密的字节数组还是字符串比对,解密都是正确的。

二、加密及解密的过程

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

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

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值