4个版本
0.1.3 | 2023年8月15日 |
---|---|
0.1.2 | 2023年6月25日 |
0.1.1 | 2023年1月9日 |
0.1.0 | 2023年1月9日 |
#914 in 密码学
35KB
519 行
Signcryption
Signcryption是一种结合了数字签名和加密功能的密码学技术。它允许发送者验证消息的来源并保护其机密性,同时允许接收者验证消息的真实性并解密它,而无需任何单独的通信渠道。
该库实现了在Ristretto255或Ed25519上实例化的Toorani-Beheshti签名加密方案。
安装
该库目前依赖于libsodium-sys-stable包。您需要先安装libsodium。
https://libsodium.gitbook.io/doc/installation
或者简单地在首次使用时使用该包的fetch-libsodium
特性,这将下载并安装当前稳定版本。
将以下内容添加到您的项目中
cargo add signcryption
或者Cargo.toml
[dependencies]
signcryption = "0.1"
使用
更高级的signcrypt
和unsigncrypt
函数会自动使用AES-GCM包进行加密。
// Default uses Ristretto255
let alice_keys = Keypair::default();
let bob_keys = Keypair::default();
let alice_public_key = alice_keys.public.clone();
let bob_public_key = bob_keys.public.clone();
let msg = "Hello".as_bytes();
// Sign and encrypt, returns a SignCrypt struct
let ciphertext = signcrypt(&alice_keys, &bob_public_key, &msg)?;
// Verify and decrypt, returns a plaintext Vec<u8>
let plaintext = unsigncrypt(ciphertext, &alice_public_key, &bob_keys)?;
assert_eq!(payload , &plaintext[..]);
要使用不同的AEAD或进行更底层的控制,您需要直接运行离散步骤函数。要删除aes-gcm包依赖,请在Cargo.toml
中设置default-features = false
Signcrypt
// Initialise state
let mut state = SignState::default();
// Using Ed25519 keys this time
let alice_keys = Keypair::new(Curve::Ed25519);
let bob_keys = Keypair::new(Curve::Ed25519);
// Shared secret for encryption
let mut crypt_key = [0u8; SHAREDBYTES];
let msg = "Hello".as_bytes()
// Additional Authenticated Data if desired
let sender_id = "alice".as_bytes()
let recipient_id = "bob".as_bytes()
let info = "rust-signcryption".as_bytes()
// Sign plaintext
sign_before(
&mut state, &mut crypt_key, &sender_id, &recipient_id, &info,
&alice.expose_secret(), &bob.public, msg, Curve::Ed25519
)?;
/////////////////////////////////////////////////////////////
// Encrypt here with your desired AEAD using crypt_key eg. //
// let cipher = ChaCha20Poly1305::new(&crypt_key); //
/////////////////////////////////////////////////////////////
// Sign ciphertext
let mut sig = [0u8; SIGNBYTES];
sign_after(&mut state, &mut sig, &alice.expose_secret(), &ciphertext, Curve::Ed25519);
// Send ciphertext, signature and any AAD to recipient
Unsigncrypt
let mut state = SignState::default();
let mut crypt_key = [0u8; SHAREDBYTES];
// Additional Authenticated Data used to signcrypt the message
let sender_id = "alice".as_bytes()
let recipient_id = "bob".as_bytes()
let info = "rust-signcryption".as_bytes()
// Verify and get shared secret
verify_before(
&mut state, &mut crypt_key, &sig, &sender_id,
&recipient_id, &info, &alice_public_key,
&bob.expose_secret(), Curve::Ed25519
)?;
////////////////////////////
// Decrypt with crypt_key //
////////////////////////////
// Verify after
verify_after(&mut state, &sig, &alice_public_key, &ciphertext, Curve::Ed25519)?;
公开验证
验证消息而不学习解密密钥。
verify_public(
&sig, &sender_id, &recipient_id, &info,
&alice_public_key, &ciphertext, Curve::Ed25519
)?;
为什么?
无论以何种顺序组合加密和签名,都存在缺陷
-
先加密后签名:攻击者可以替换您的签名,使其看起来像他们加密了文件。
-
先签名后加密:接收者可以重新加密文件并冒充您将文件发送给其他人。
Signcryption在加密阶段之前和之后都执行签名,从而消除了这些缺陷。
替代方案
该包基于由Frank Denis编写的C语言Libsodium-Signcryption库。
许可
所有crates都根据您的选择在以下两种许可下提供
任选其一。
贡献
除非您明确声明,否则您有意提交给作品的所有贡献,根据Apache-2.0许可定义,应如上所述双重许可,不得添加任何额外的条款或条件。
依赖关系
~2.6–5MB
~54K SLoC