rust-crypto
主要介绍rust-crypto和tiny-keccak这两个Rust实现的密码学库。
rust-crypto
Rust实现的密码学库,包含了密码学中常用的对称密码、公钥密码、单向散列函数、消息认证码、数字签名、随机数生成器等算法。目前支持以下算法:
Name | Description |
---|---|
AES | 高级加密标准(Advanced Encryption Standard)为最常见的对称加密算法 |
Bcrypt | 专门为密码存储而设计的算法,基于Blowfish加密算法变形而来,是一个跨平台的文件加密工具 |
BLAKE2b | BLAKE的64位版本,它可以生成最高512位的任意长度哈希 |
BLAKE2s | BLAKE的32位版本,它可以生成最高256位的任意长度哈希 |
Blowfish | Blowfish算法是一个64位分组及可变密钥长度的对称密钥分组密码算法 |
ChaCha20 | ChaCha系列流密码,作为salsa密码的改良版,具有更强的抵抗密码分析攻击的特性,“20”表示该算法有20轮的加密计算 |
Curve25519 | Curve25519 是目前最高水平的 Diffie-Hellman函数,适用于广泛的场景,由Daniel J. Bernstein教授设计 |
ECB, CBC, and CTR block cipher modes | ECB模式、CBC模式、CTR模式(分组密码模式) |
Ed25519 | Ed25519是一个数字签名算法,签名和验证的性能都极高 |
Fortuna | 一种密码学安全的随机数发生器,适用于长生命周期的任务 |
Ghash | An implementaiton of GHASH as used in GCM |
HC128 | HC-128算法是HC-256算法的简化版,为欧洲e STREAM工程最终胜出的7个序列密码算法之一。HC-128由初始化算法和密钥流产生算法两部分构成,为基于表驱动的适于软件实现的算法。 |
HMAC | 散列消息身份验证码(Hashed Message Authentication Code) |
MD5 | Message-Digest Algorithm 5(信息-摘要算法5),为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护 |
PBKDF2 | Password-Based Key Derivation Function 2 |
PKCS padding for CBC block cipher mode | 分组密码CBC模式PKCS填充 |
Poly1305 | A cryptographic message authentication code (MAC) created by Daniel J. Bernstein |
RC4 | 一种对称加密算法,RSA三人组中的头号人物Ronald Rivest在1987年设计的密钥长度可变的流加密算法簇 |
RIPEMD-160 | RACE Integrity Primitives Evaluation Message Digest,RACE原始完整性校验消息摘要(比特币中有应用) |
Salsa20 and XSalsa20 | Salsa20是由Daniel J.Bernstein提出的基于hash函数设计的流密码算法 |
Scrypt | 一种内存依赖型hash算法(区块链中有应用) |
Sha1 | 安全哈希算法(Secure Hash Algorithm 1) |
Sha2 (All fixed output size variants) | SHA-2 (Secure Hash Algorithm 2) |
Sha3 | SHA-3 (Secure Hash Algorithm 3) |
Sosemanuk | 一种基于软件的流密码算法 |
Whirlpool | 一种基于分组密码的散列算法 |
代码示例1
//! SHA3-256 示例
extern crate crypto;
extern crate rustc_hex;
use self::crypto::digest::Digest;
use self::crypto::sha3::Sha3;
use rustc_hex::{ToHex,FromHex};
fn main() {
// create a SHA3-256 object
let mut hasher = Sha3::sha3_256();
// write input message
hasher.input_str("hello world");
// read hash digest
let hex = hasher.result_str();
let res=hex.from_hex().unwrap();
let res=res.as_slice();
let expected: &[u8] = &[
0x64, 0x4b, 0xcc, 0x7e, 0x56, 0x43, 0x73, 0x04,
0x09, 0x99, 0xaa, 0xc8, 0x9e, 0x76, 0x22, 0xf3,
0xca, 0x71, 0xfb, 0xa1, 0xd9, 0x72, 0xfd, 0x94,
0xa3, 0x1c, 0x3b, 0xfb, 0xf2, 0x4e, 0x39, 0x38
];
assert_eq!(res,expected);
}
代码示例2
//! AES256 CBC、CTR mode encrypt decrypt demo
use std::str;
use crypto::{symmetriccipher,buffer,aes,blockmodes};
use crypto::buffer::{ReadBuffer,WriteBuffer,BufferResult};
use crypto::aessafe::*;
use crypto::blockmodes::*;
use crypto::symmetriccipher::*;
use rand::{Rng,OsRng};
pub fn aes_cbc_mode(){
let message="Hello World!";
let mut key:[u8;32]=[0;32];
let mut iv:[u8;16]=[0;16];
// In a real program, the key and iv may be determined
// using some other mechanism. If a password is to be used
// as a key, an algorithm like PBKDF2, Bcrypt, or Scrypt (all
// supported by Rust-Crypto!) would be a good choice to derive
// a password. For the purposes of this example, the key and
// iv are just random values.
let mut rng=OsRng::new().ok().unwrap();
rng.fill_bytes(&mut key);
rng.fill_bytes(&mut iv);
let encrypted_data=aes256_cbc_encrypt(message.as_bytes(),&key,&iv).ok().unwrap();
let decrypted_data=aes256_cbc_decrypt(&encrypted_data[..],&key,&iv).ok().unwrap();
let crypt_message=str::from_utf8(decrypted_data.as_slice()).unwrap();
assert_eq!(message,crypt_message);
println!("{}",crypt_message);
}
// Encrypt a buffer with the given key and iv using AES-256/CBC/Pkcs encryption.
fn aes256_cbc_encrypt(data: &[u8],key: &[u8], iv: &[u8])->Result<Vec<u8>,symmetriccipher::SymmetricCipherError>{
let mut encryptor=aes::cbc_encryptor(
aes::KeySize::KeySize256,
key,
iv,
blockmodes::PkcsPadding);
let mut final_result=Vec::<u8>::new();
let mut read_buffer=buffer