rust - 基于AES-CBC-128的双重加密实现

通常加密密钥不要出现在源码中,比如配置文件中的数据库密码等。解决方案通常采用将密钥存放在环境变量中,进程启动时从环境变量获取密钥加载到内存中。

还有一种方案,对密钥进行加密,源码中只包含对密钥加密的根密钥和对密钥加密后的二次密钥,如果不知道加密方式,在编译出来的二进制文件中很难还原出真实的密钥。

安装依赖

cargo add base64
cargo add rust-crypto

AES128加解密算法

use base64::{engine::general_purpose, Engine as _};
use crypto::buffer::{BufferResult, ReadBuffer, WriteBuffer};
use crypto::{aes, blockmodes, buffer, symmetriccipher};


pub fn aes128_cbc_encrypt(
    data: &[u8],
    key: &[u8],
    iv: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut encryptor = aes::cbc_encryptor(
        aes::KeySize::KeySize128,
        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 =
            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)
}

pub fn aes128_cbc_decrypt(
    encrypted_data: &[u8],
    key: &[u8],
    iv: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = aes::cbc_decryptor(
        aes::KeySize::KeySize128,
        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 =
            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)
}

base64编码得到二次密钥

将加密后的秘钥存放在配置文件中。

pub fn aes128_base64_encrypt(
    key: &[u8],
    iv: &[u8],
    plain_text: &[u8],
) -> String {
    let output = aes128_cbc_encrypt(plain_text, &key, &iv).unwrap();
    general_purpose::STANDARD.encode(&output)
}

base64解码获得真实的密钥

首先从配置文件中获取二次加密的秘钥,解密获得真实的秘钥,然后再用解密后的秘钥对密文进行解密 或 对明文进行加密。

pub fn aes128_base64_decrypt(
    key: &[u8],
    iv: &[u8],
    cipher_text: &[u8],
) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let data = general_purpose::STANDARD.decode(cipher_text).unwrap();
    aes128_cbc_decrypt(&data, &key, &iv)
}

单元测试

#[test]
fn test_aes128_cbc() {
    let key = get_random_key16();
    let iv = generate_iv();

    // 加密
    let plain_text = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!".to_string();
    let cipher_text = aes128_base64_encrypt(&key, &iv, plain_text.as_bytes());
    // 加密
    let output =
        aes128_base64_decrypt(&key, &iv, cipher_text.as_bytes()).unwrap();
    let plain_text_2 = String::from_utf8(output).unwrap();

    assert_eq!(plain_text, plain_text_2);
}

相关推荐

  1. rust - 基于AES-CBC-128双重加密实现

    2024-03-23 18:26:01       41 阅读
  2. rust - 基于AES-CBC-128图片加密实现

    2024-03-23 18:26:01       37 阅读
  3. C# AES-128-CBC 加密

    2024-03-23 18:26:01       51 阅读
  4. 代码示例:OpenSSL AES CBC 加密

    2024-03-23 18:26:01       32 阅读
  5. iOS MT19937随机数生成,结合AES-CBC加密算法实现

    2024-03-23 18:26:01       27 阅读
  6. 【Go】使用Go语言实现AES CBC No Padding加密和解密

    2024-03-23 18:26:01       32 阅读
  7. openssl3.2 - exp - aes-128-cbc

    2024-03-23 18:26:01       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-23 18:26:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-23 18:26:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-23 18:26:01       87 阅读
  4. Python语言-面向对象

    2024-03-23 18:26:01       96 阅读

热门阅读

  1. vue生命周期 和 最常用的mounted

    2024-03-23 18:26:01       37 阅读
  2. 物联网如何改善供应链的透明度和效率

    2024-03-23 18:26:01       42 阅读
  3. 关于Linux环境下的LXD及Docker提权

    2024-03-23 18:26:01       41 阅读
  4. dockers compose up 报no configuration file provided: not found

    2024-03-23 18:26:01       36 阅读
  5. H5 与 App、网页之间的通信

    2024-03-23 18:26:01       46 阅读
  6. 解锁算法效率:掌握时间复杂度O(n)的艺术

    2024-03-23 18:26:01       36 阅读
  7. TypeScript 数据类型

    2024-03-23 18:26:01       39 阅读