入门:

ChaCha20-Poly1305 是一个组合了流加密算法(ChaCha20)和消息认证码(Poly1305)的加密方案
ChaCha20 是一种流加密算法,设计用于效率高且安全性强的加密。它是 Salsa20 的一个变种,通过更好的设计提高了性能和安全性。
工作原理:ChaCha20 使用一个 256 位的对称密钥和一个 96 位的 nonce。通过这些,ChaCha20 会生成一个伪随机密钥流,并将其与明文按位异或来生成密文。解密过程则是相同的操作:将相同的密钥流与密文按位异或来还原明文。

Poly1305 是一个消息认证码(MAC),用于确保消息的完整性和真实性。它使用同一个密钥生成一个认证标签(auth tag),这个标签用于验证消息没有被篡改。
工作原理:Poly1305 采用一个 256 位的密钥,生成对消息的认证标签。当消息需要验证时,接收方会使用同样的密钥来计算消息的认证标签,并与发送方计算的标签进行对比,从而确认消息的完整性和真实性。
为什么是安全的
高效且经过验证:两者(ChaCha20 和 Poly1305)的设计都考虑了高效性和安全性,已经经过广泛的学术测试和实地应用。
合并使用:ChaCha20 提供了保密性(Confidentiality)、Poly1305 提供完整性 (Integrity) 和真实性 (Authenticity),将二者结合在一起形成一个同时提供保密性和完整性的加密方案。

使用椭圆曲线 Diffie-Hellman (ECDH) 算法进行密钥交换,以 X25519 曲线为例:
私钥:每一方(客户端和服务器)都有一个独立生成的私钥(通常称为 StaticSecret),这是一个随机生成的数。
公钥:每一方使用这个私钥生成对应的公钥(称为 PublicKey),公钥是一个点乘运算结果,以便与私钥安全地共享。
计算共享密钥
公共密钥交换:客户端和服务器相互交换公钥。
共享密钥计算:
客户端用服务器的公钥和自己的私钥进行点乘运算,生成共享密钥。
服务器用客户端的公钥和自己的私钥进行同样的计算,生成一致的共享密钥。

BLAKE2

是一种高效的密码学哈希函数,用于生成一个固定长度的哈希值。它的设计目标是快速且安全。
安全性原理

  • 抗碰撞性:输入可以具有较大不同,但产生相同输出的可能性极小。
  • 确定性:同一输入总是生成同一输出
  • 抗算法攻击:BLAKE2 针对了一些目前已知的攻击方法设计更为安全,抵抗常见的哈希冲撞和预像攻击。
  • 为什么要进行哈希处理?
  • 密钥长度:确保生成的共享密钥适合用于对称加密算法(32 字节长度适用于 ChaCha20Poly1305)。
  • 统一格式:在共享密钥生成过程后,将其规整为适配的密钥格式,确保安全性。
fn encrypt_data(private_key: &StaticSecret, peer_public: &PublicKey, data: &mut [u8]) -> Vec<u8> {
    // 1. 使用客户端的私钥和服务器的公钥计算出共享密钥
    let shared_secret = private_key.diffie_hellman(peer_public);
    // 2. 使用 BLAKE2 哈希函数对共享密钥进行哈希处理,产生 32 字节用于对称加密的密钥
    let mut hasher = Blake2s::new();
    hasher.update(shared_secret.as_bytes());
    let key_bytes = hasher.finalize();
    let key = Key::from_slice(&key_bytes[..32]);  // ChaCha20Poly1305 的密钥长度应该为 32 字节
    // 3. 使用生成的对称加密密钥创建 ChaCha20Poly1305 实例
    let cipher = ChaCha20Poly1305::new(key);
    // 4. 构建数据的副本,这里使用了 Vec<u8>,它将成为实际加密操作的目标数据
    let mut buffer = data.to_vec();
    // 5. 生成一个唯一的 Nonce 用于本次加密操作
    let nonce = generate_nonce();
    // 6. 使用 nonce 和对称加密实例对数据进行加密操作
    cipher.encrypt_in_place(&nonce, b"", &mut buffer).expect("encryption failure!");
    // 7. 将 nonce 附加到加密数据包的头部,以便解密时能够使用相同的 nonce
    let mut encrypted_packet = Vec::from(nonce.as_slice());
    encrypted_packet.extend_from_slice(&buffer);
    // 8. 返回包含 nonce 和加密数据的最终数据包
    encrypted_packet
}

fn decrypt_data(private_key: &StaticSecret, peer_public: &PublicKey, data: &mut [u8]) -> Vec<u8> {
    if data.len() < 12 {  // Nonce length check
        panic!("Received packet is too short");
    }

    let (nonce_bytes, ciphertext) = data.split_at(12);
    let shared_secret = private_key.diffie_hellman(peer_public);
    let mut hasher = Blake2s::new();
    hasher.update(shared_secret.as_bytes());
    let key_bytes = hasher.finalize();
    let key = Key::from_slice(&key_bytes[..32]);  // ChaCha20Poly1305 的密钥长度应该为 32 字节
    let cipher = ChaCha20Poly1305::new(key);  // 这里创建 ChaCha20Poly1305 实例

    let mut buffer = ciphertext.to_vec();
    let nonce = Nonce::from_slice(nonce_bytes).expect("Invalid nonce length");

    cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!");
    buffer
}

putao
8 声望1 粉丝

推动世界向前发展,改善民生。