带有Rust的AES-256-CBC加密


目的

尝试使用Rust加密和解密AES-256-CBC。我将尝试使用Ruby对其进行解密。
16字节的IV存储在加密字符串的开头。

用Rust加密和解密

货代

1
2
3
4
5
aes = "0.3.2"
base64 = "0.12.0"
block-modes = "0.3.3"
bytebuffer = "0.2.1"
rand = "0.7.3"

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
use aes::Aes256;
use block_modes::{BlockMode, Cbc};
use block_modes::block_padding::Pkcs7;
use rand::seq::SliceRandom;

type AesCbc = Cbc<Aes256, Pkcs7>;

// ランダム文字列の元
const BASE_STR: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

// IV用にランダム文字列生成
fn gen_ascii_chars(size: usize) -> String {
    let mut rng = &mut rand::thread_rng();
    String::from_utf8(
        BASE_STR.as_bytes()
            .choose_multiple(&mut rng, size)
            .cloned()
            .collect()
    ).unwrap()
}

// 暗号化
fn encrypt(key: &str, data: &str) -> String {
    let iv_str = gen_ascii_chars(16);
    let iv = iv_str.as_bytes();
    let cipher = AesCbc::new_var(key.as_bytes(), iv).unwrap();
    let ciphertext = cipher.encrypt_vec(data.as_bytes());
    let mut buffer = bytebuffer::ByteBuffer::from_bytes(iv);
    buffer.write_bytes(&ciphertext);
    base64::encode(buffer.to_bytes())
}

// 復号化
fn decrypt(key: &str, data: &str) -> String {
    let bytes = base64::decode(data).unwrap();
    let cipher = AesCbc::new_var(key.as_bytes(), &bytes[0..16]).unwrap();
    String::from_utf8(cipher.decrypt_vec(&bytes[16..]).unwrap()).unwrap()
}

fn main() {
    let plaintext = "予定表~①??????だ";
    let key = "01234567012345670123456701234567";
    let enc = encrypt(key, plaintext);
    println!("{}", enc);
    let dec = decrypt(key, &enc);
    assert_eq!(plaintext, dec);
    println!("{}", dec);
}

用Ruby解密

main.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'openssl'
require 'base64'

key = "01234567012345670123456701234567"
encrypted_text = ARGV[0]
encrypted_data = Base64.decode64(encrypted_text)

dec = OpenSSL::Cipher.new('AES-256-CBC')
dec.decrypt
dec.key = key
dec.iv = encrypted_data[0..15]
decrypted_data = dec.update(encrypted_data[16..]) + dec.final
decrypted_data.force_encoding("UTF-8")
puts decrypted_data
puts decrypted_data == "予定表~①??????だ"