我正在使用 Rust 中的对称加密 gem 解密 Ruby on Rails 应用程序创建的遗留数据。请参阅我之前的问题如何用另一种语言解密由 Ruby 的“对称加密”gem 加密的数据? https://stackoverflow.com/questions/47661306/.
我已经在 Node 中实现了这个,其中加密库似乎知道如何去除 Rust 的加密字符串中的乱码。openssl crate https://crates.io/crates/openssl并没有剥离(至少,我使用它的方式)。我已经去掉了 PKCS7 填充和标头,但它仍然存在。那个官样文章是什么?我如何让 Rust 删除它?
加密数据以具有固定大小标头的明文形式开始,使用 AES-128-CBC 和 PKCS7 填充进行加密,然后进行 Base64 编码。使用 Node,我可以使用以下代码正确解密它:
const crypto = require("crypto");
const KEY = Buffer.from("1234567890ABCDEF");
const IV = Buffer.from("1234567890ABCDEF");
const CIPHERTEXT = Buffer.from("QEVuQwBAEACuPUPByDkk5jyNzQ3Wd3xTy2Isihz62XTLe1M5qKQrvw==", "base64");
const HEADER_SIZE = 8;
const ALGO = "aes-128-cbc";
const decipher = crypto.createDecipheriv(ALGO, KEY, IV);
decipher.update(CIPHERTEXT.slice(HEADER_SIZE));
const result = decipher.final();
console.log([...result]);
console.log(result.toString());
结果是
[ 72, 97, 108, 102 ]
Half
我更喜欢将 Rust 用于我正在编写的应用程序。使用openssl
我可以解码加密数据,但是 Node 的库知道如何删除一堆垃圾,但 Rust 不会按照我使用它的方式自动删除:
extern crate base64;
extern crate openssl;
use openssl::symm::*;
const KEY: &'static [u8] = b"1234567890ABCDEF";
const IV: &'static [u8] = b"1234567890ABCDEF";
const CIPHERTEXT: &'static str = "QEVuQwBAEACuPUPByDkk5jyNzQ3Wd3xTy2Isihz62XTLe1M5qKQrvw==";
const HEADER_SIZE: usize = 8;
fn main() {
let decoded = base64::decode(&CIPHERTEXT).unwrap();
let ciphertext = &decoded[HEADER_SIZE..];
let result = decrypt(Cipher::aes_128_cbc(), KEY, Some(IV), ciphertext).unwrap();
println!("{:?}", result);
println!("{:?}", String::from_utf8_lossy(&result));
}
结果是
[221, 75, 14, 215, 54, 120, 246, 222, 194, 208, 53, 68, 127, 190, 124, 8, 72, 97, 108, 102]
"�K\u{e}�6x����5D\u{7f}�|\u{8}Half"
您可以看到最后 4 个字节是正确的,但该 Node 删除了前面的 16 个字节,因为它看起来应该有。我不知道这些字节是什么。
起初我以为这 16 个字节的乱码来自于尝试解密 PKCS7 填充。但我可以验证填充已经被删除:如果我创建一个Crypter
按照中的示例openssl
板条箱的文档 https://docs.rs/openssl/0.10.4/openssl/symm/struct.Crypter.html,但不包括truncate()
步骤,得到的结果Vec
已连续12次12
s — PKCS7 填充 — 已自动删除。
所以乱码不是 PKCS7 填充,但我不知道它是什么,也不知道如何使用 Rust 摆脱它。
并预见到米兰达关于如果我不是专家就不要乱搞加密的警告:这不会在生产中使用或创建数据以投入生产。