NSec.Cryptography 使用 ChaCha20Poly1305 和 SharedSecret 加密解密

NSec.Cryptography encrypt and decrypt using ChaCha20Poly1305 and SharedSecret

我正在尝试使用 NSec.Cryptography 加密(和解密)从一台设备发送到另一台设备的消息,但我发现文档有点含糊。据我了解,我分别需要设备 A 和 B 的 KeyPublicKey。我可以把它们变成 SharedSecret:

var sharedSecret = KeyAgreementAlgorithm.X25519.Agree(encryption.Key, deviceKey);

但是,此共享秘密似乎对加密没有用,因为 Encrypt(...) 方法要求在其参数中输入密钥:

var cyphertext = AeadAlgorithm.ChaCha20Poly1305.Encrypt(sharedSecret, nonce, new byte[0], message);
                                                              ^-- will not work

我有多个问题:

  1. SharedSecret不能用来加密有什么用?
  2. 如果 ChaCha20Poly1305.Encrypt 方法使用一个不能作为共享密钥的密钥,它有什么用处?
  3. 如何使用 A 的私钥和 B 的 public 密钥(如 libsodium 中的 box 和 secret box)加密消息?

注意:我想使用 X25519 密钥。

阅读 SharedSecret 的文档:

Represents the output of a key agreement and the input for key derivation

所以您首先需要使用特定的 KDF 生成一个或多个密钥,而 NSec 似乎实现了 HKDF(使用 SHA-256 或-512,我更喜欢后者,因为它更安全并且 - 在 64 位上机器 - 可能更快。共享秘密本身对对手来说并不是完全随机的,因此需要 KDF 从中创建最加密安全的密钥。

这应该回答 1 和 2:SharedSecret 用于派生实际密钥,它本身不是密钥。

How do I encrypt a message using the private key of A and public key of B (like box and secret box in libsodium)?

至于3:需要发送方A的临时密钥对和接收方B的public密钥,然后进行密钥协商&密钥派生(如上所述)使用发件人的临时私钥并发送带有密文的临时 public 密钥。不要忘记在密钥协商后销毁发送方的临时私钥;你不再需要它了,泄露它会危及密文。

接收方现在可以使用他们的静态私钥和收到的临时 public 密钥执行相同的协议,并最终解密消息。