4 个版本 (2 个破坏性更新)
0.10.0 | 2021年12月28日 |
---|---|
0.9.0 | 2020年6月12日 |
0.8.0 | 2019年2月11日 |
0.8.0-rc1 | 2018年12月13日 |
#38 在 #md5
43,242 每月下载量
用于 3 个包
2KB
RustCrypto: 哈希函数
纯Rust编写的加密哈希函数集合。
所有算法都位于独立的包中,并使用digest
包中的特性实现。此外,所有包都不需要标准库(即 no_std
支持)并且可以轻松用于裸机或WebAssembly编程。
支持的算法
注意:对于新应用,或在不考虑与其他现有标准兼容性的情况下,我们强烈建议使用BLAKE2、SHA-2或SHA-3。
算法 | 包 | Crates.io | 文档 | MSRV | 安全性 |
---|---|---|---|---|---|
Ascon 哈希 | ascon-hash |
💚 | |||
BelT 哈希 | belt-hash |
💚 | |||
BLAKE2 | blake2 |
💚 | |||
FSB | fsb |
💚 | |||
GOST R 34.11-94 | gost94 |
💛 | |||
Grøstl (Groestl) | groestl |
💚 | |||
JH | jh |
💚 | |||
KangarooTwelve | k12 |
💚 | |||
MD2 | md2 |
💔 | |||
MD4 | md4 |
💔 | |||
MD5 | md5 ❗ |
💔 | |||
RIPEMD | ripemd |
💚 | |||
SHA-1 | sha1 |
💔 | |||
SHA-1 检查 | sha1-checked |
💛 | |||
SHA-2 | sha2 |
💚 | |||
SHA-3 (Keccak) | sha3 |
💚 | |||
SHABAL | shabal |
💚 | |||
Skein | skein |
💚 | |||
SM3 (OSCCA GM/T 0004-2012) | sm3 |
💚 | |||
Streebog (GOST R 34.11-2012) | streebog |
💛 | |||
Tiger | tiger |
💚 | |||
Whirlpool | whirlpool |
💚 |
注意:该blake3
包实现了此存储库中其余哈希函数使用的 digest
特性,但由 BLAKE3 团队维护。
安全性等级说明
以下描述了与每个哈希函数(即算法,而不是具体实现)相关的安全性等级评分
心形符号 | 描述 |
---|---|
💚 | 没有已知的成功攻击 |
💛 | 理论上的破解:安全性低于声明的 |
💔 | 实践中已证明的攻击:尽可能避免 |
请参阅维基百科上的安全性页面以获取更多信息。
crate名称
尽可能情况下,crate的发布名与crate文件夹名相同。md5的拥有者拒绝参与此项目。这个crate没有实现digest
特性,因此它不能与RustCrypto生态系统互操作。这就是为什么我们以md-5
的形式发布我们的MD5实现,并用❗标记它。请注意,库本身命名为md5
,即在use
语句中,您应该使用md5
,而不是md_5
。
SHA-1实现之前以sha-1
的形式发布,但自v0.10.0版本以来迁移到sha1
。 sha-1
将继续接收v0.10.x补丁更新,但将在sha1
v0.11版本发布后弃用。
最低支持的Rust版本(MSRV)策略
MSRV的升级被视为破坏性更改,并且只有在进行小版本升级时才会执行。
示例
让我们以SHA-2为例,演示如何使用此存储库中的crate。
首先将sha2
crate添加到您的Cargo.toml
[dependencies]
sha2 = "0.10"
请注意,此存储库中的所有crate都有一个默认启用的std
功能。因此,如果您计划在no_std
环境中使用crate,请务必禁用它
[dependencies]
sha2 = { version = "0.10", default-features = false }
sha2
和其他哈希实现crate为了方便起见重新导出digest
crate和Digest
特性,因此您不需要在Cargo.toml
中将其作为显式依赖项。
现在您可以编写以下代码
use sha2::{Sha256, Digest};
let mut hasher = Sha256::new();
let data = b"Hello world!";
hasher.update(data);
// `update` can be called repeatedly and is generic over `AsRef<[u8]>`
hasher.update("String data");
// Note that calling `finalize()` consumes hasher
let hash = hasher.finalize();
println!("Binary hash: {:?}", hash);
在这个例子中,hash
的类型是GenericArray<u8, U32>
,它是generic-array
crate中定义的[u8; 32]
的泛型替代品。如果您需要将哈希值序列化为字符串,可以使用base16ct
和base64ct
等crate
use base64ct::{Base64, Encoding};
let base64_hash = Base64::encode_string(&hash);
println!("Base64-encoded hash: {}", base64_hash);
let hex_hash = base16ct::lower::encode_string(&hash);
println!("Hex-encoded hash: {}", hex_hash);
除了调用update
之外,您还可以使用链式方法
use sha2::{Sha256, Digest};
let hash = Sha256::new()
.chain_update(b"Hello world!")
.chain_update("String data")
.finalize();
如果有一个完整的消息可用,则可以使用方便的Digest::digest
方法
use sha2::{Sha256, Digest};
let hash = Sha256::digest(b"my message");
哈希可读对象
如果您想对实现了Read
特质的类型的数据进行哈希,则可以依赖于Write
特质的实现(需要默认启用的std
功能)
use sha2::{Sha256, Digest};
use std::{fs, io};
let mut file = fs::File::open(&path)?;
let mut hasher = Sha256::new();
let n = io::copy(&mut file, &mut hasher)?;
let hash = hasher.finalize();
基于哈希的消息认证码(HMAC)
如果您想计算基于哈希的消息认证码 (HMAC),可以使用来自 hmac
包的通用实现,该包是 RustCrypto/MACs 存储库的一部分。
通用代码
您可以在 Digest
特性(或来自 digest
包的其他特性)上编写通用代码,它可以在不同的哈希函数上运行
use sha2::{Sha256, Sha512, Digest};
// Toy example, do not use it in practice!
// Instead use crates from: https://github.com/RustCrypto/password-hashing
fn hash_password<D: Digest>(password: &str, salt: &str, output: &mut [u8]) {
let mut hasher = D::new();
hasher.update(password.as_bytes());
hasher.update(b"$");
hasher.update(salt.as_bytes());
output.copy_from_slice(&hasher.finalize())
}
let mut buf1 = [0u8; 32];
hash_password::<Sha256>("my_password", "abcd", &mut buf1);
let mut buf2 = [0u8; 64];
hash_password::<Sha512>("my_password", "abcd", &mut buf2);
如果您想使用具有特性对象(trait objects)的哈希函数,可以使用 DynDigest
特性
use digest::DynDigest;
// Dynamic hash function
fn use_hasher(hasher: &mut dyn DynDigest, data: &[u8]) -> Box<[u8]> {
hasher.update(data);
hasher.finalize_reset()
}
// You can use something like this when parsing user input, CLI arguments, etc.
// DynDigest needs to be boxed here, since function return should be sized.
fn select_hasher(s: &str) -> Box<dyn DynDigest> {
match s {
"md5" => Box::new(md5::Md5::default()),
"sha1" => Box::new(sha1::Sha1::default()),
"sha224" => Box::new(sha2::Sha224::default()),
"sha256" => Box::new(sha2::Sha256::default()),
"sha384" => Box::new(sha2::Sha384::default()),
"sha512" => Box::new(sha2::Sha512::default()),
_ => unimplemented!("unsupported digest: {}", s),
}
}
let mut hasher1 = select_hasher("md5");
let mut hasher2 = select_hasher("sha512");
// the `&mut *hasher` is to DerefMut the value out of the Box
// this is equivalent to `DerefMut::deref_mut(&mut hasher)`
// can be reused due to `finalize_reset()`
let hash1_1 = use_hasher(&mut *hasher1, b"foo");
let hash1_2 = use_hasher(&mut *hasher1, b"bar");
let hash2_1 = use_hasher(&mut *hasher2, b"foo");
许可证
本存储库中的所有包都根据以下其中之一进行许可:
由您选择。
贡献
除非您明确声明,否则您提交的任何旨在包含在本作品中的贡献(根据 Apache-2.0 许可证定义),都将按上述方式双许可,无需任何附加条款或条件。