8 个版本

0.1.6 2020 年 12 月 10 日
0.1.5 2020 年 11 月 16 日
0.0.1 2020 年 8 月 4 日

1793加密学

Download history 2/week @ 2024-02-25 5/week @ 2024-03-10 108/week @ 2024-03-31

每月下载量 113

Apache-2.0

165KB
2K SLoC

YACA 的 Rust 绑定

crate docs license repo

绑定要工作,需要 YACA 库。

YACA - 另一个加密 API

YACA 是一个简单的、但功能强大的 OpenSSL 库包装器。它使用简单易用的 API 包装常见的、最广泛使用的加密操作。

查看文档的 主页 以获取快速示例。
tests 目录包含更多所有可用 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