8 个版本
0.1.6 | 2020 年 12 月 10 日 |
---|---|
0.1.5 | 2020 年 11 月 16 日 |
0.0.1 | 2020 年 8 月 4 日 |
1793 在 加密学
每月下载量 113
165KB
2K SLoC
YACA 的 Rust 绑定
绑定要工作,需要 YACA 库。
YACA - 另一个加密 API
YACA 是一个简单的、但功能强大的 OpenSSL 库包装器。它使用简单易用的 API 包装常见的、最广泛使用的加密操作。
lib.rs
:
YACA - 另一个加密 API。C 库 YACA 的绑定
示例
use std::ffi::CString;
use yaca::{self, prelude::*};
use yaca::{Key, KeyType, KeyLength, KeyFormat, KeyFileFormat, EncryptContext,
DecryptContext, EncryptAlgorithm, BlockCipherMode, Padding};
pub const MSG: &[u8] = b"Lorem ipsum dolor sit amet.";
fn main() -> Result<(), Box<dyn std::error::Error>>
{
// Start
yaca::initialize()?;
// Key generate/export/import example:
let key = Key::generate(&KeyType::RsaPrivate,
&KeyLength::Bits(512))?;
let p = CString::new("password")?;
let data = key.export(&KeyFormat::Default, &KeyFileFormat::Pem, Some(&p))?;
let key = Key::import(&data, &KeyType::RsaPrivate, Some(&p))?;
println!("{:?}: {:?}", key.get_type()?, key.get_length()?);
// Encrypt/decrypt example:
// Prepare
let algo = EncryptAlgorithm::Aes;
let cbc = BlockCipherMode::Cbc;
let key_len = KeyLength::Bits(256);
let sym_key = Key::generate(&KeyType::Symmetric, &key_len)?;
let iv_len = EncryptContext::get_iv_length(&algo, &cbc, &key_len)?;
let iv = match &iv_len {
None => None,
Some(x) => Some(Key::generate(&KeyType::Iv, x)?),
};
if let Some(x) = &iv {
println!("IV_used: {:?}: {:?}", x.get_type()?, x.get_length()?);
};
// Encrypt
let ctx = EncryptContext::initialize(&algo, &cbc, &sym_key, iv.as_ref())?;
ctx.set_property_padding(&Padding::Pkcs7)?;
let mut cipher: Vec<u8> = Vec::new();
for i in MSG.chunks(5) {
cipher.append(&mut ctx.update(i)?);
};
cipher.append(&mut ctx.finalize()?);
// Decrypt
let ctx = DecryptContext::initialize(&algo, &cbc, &sym_key, iv.as_ref())?;
ctx.set_property_padding(&Padding::Pkcs7)?;
let mut plain: Vec<u8> = Vec::new();
for i in cipher.chunks(5) {
plain.append(&mut ctx.update(i)?);
};
plain.append(&mut ctx.finalize()?);
// Check
assert_eq!(MSG, plain);
let plain = CString::new(plain)?;
println!("{}", plain.to_str()?);
// Finish
Ok(yaca::cleanup())
}
简单 API
由名为 Yaca::simple_*
的函数定义
设计约束
- 所有操作都是单次(无法进行流式传输)
- 不使用上下文
- 仅支持摘要、签名和对称加密
- 不支持禁用 PKCS#7 填充以用于 ECB 和 CBC 链接
- 不支持更改签名/验证的默认 PKCS#1 填充
- 不支持 GCM 和 CCM 链接
- 不支持 RC2 有效密钥位属性
use std::ffi::CString;
use yaca::{self, prelude::*};
use yaca::{Key, KeyType, KeyLength, EncryptAlgorithm, BlockCipherMode};
pub const MSG: &[u8] = b"Lorem ipsum dolor sit amet.";
fn main() -> Result<(), Box<dyn std::error::Error>>
{
// Start
yaca::initialize()?;
// Simple encrypt/decrypt of empty data
let sym_key = Key::generate(&KeyType::Symmetric, &KeyLength::Bits(256))?;
let v = yaca::simple_encrypt(&EncryptAlgorithm::UnsafeRc4, &BlockCipherMode::None,
&sym_key, None, &Vec::new())?;
assert!(v.is_empty());
let v = yaca::simple_decrypt(&EncryptAlgorithm::UnsafeRc4, &BlockCipherMode::None,
&sym_key, None, &Vec::new())?;
assert!(v.is_empty());
// Simple encrypt/decrypt
let iv = Key::generate(&KeyType::Iv, &KeyLength::Bits(128))?;
let cipher = yaca::simple_encrypt(&EncryptAlgorithm::Aes, &BlockCipherMode::Cbc,
&sym_key, Some(&iv), MSG)?;
let plain = yaca::simple_decrypt(&EncryptAlgorithm::Aes, &BlockCipherMode::Cbc,
&sym_key, Some(&iv), &cipher)?;
// Check for simple
assert_eq!(MSG, plain);
let plain = CString::new(plain)?;
println!("{}", plain.to_str()?);
// Finish
Ok(yaca::cleanup())
}
依赖项
~145–250KB