2

我正在尝试使用 NSec.Cryptography 加密(和解密)从一台设备发送到另一台设备的消息,但我发现文档有点含糊。据我了解,我分别需要设备 A 和 B 的 aKeyPublicKey。我可以把这些变成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 的公钥加密消息(如 libsodium 中的盒子和秘密盒子)?

注意:我想使用 X25519 键。

4

1 回答 1

2

阅读以下文档SharedSecret

表示密钥协议的输出和密钥派生的输入

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

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

如何使用 A 的私钥和 B 的公钥加密消息(如 libsodium 中的盒子和秘密盒子)?

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

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

于 2019-12-12T17:14:27.777 回答