NSec.Cryptography шифрует и расшифровывает с помощью ChaCha20Poly1305 и SharedSecret

Я пытаюсь зашифровать (и расшифровать) сообщения, отправляемые с одного устройства на другое, с помощью NSec.Cryptography, но я нахожу документацию немного расплывчатой. Как я понял мне нужны Key и PublicKey устройства А и Б соответственно. Я могу превратить их в 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.


person Yuri van Geffen    schedule 12.12.2019    source источник


Ответы (1)


Прочтите документацию для 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 используется для получения фактических ключей, это не ключ сам по себе.

Как зашифровать сообщение, используя закрытый ключ A и открытый ключ B (например, ящик и секретный ящик в libsodium)?

Что касается 3: вам нужна пара эфемерных ключей для отправителя A и открытый ключ получателя B. Затем вы выполняете соглашение о ключе и получение ключа (как указано выше), используя эфемерный закрытый ключ отправителя и отправляете эфемерный открытый ключ с зашифрованным текстом. Не забудьте уничтожить эфемерный закрытый ключ отправителя после согласования ключей; он вам больше не нужен, а его утечка скомпрометирует зашифрованный текст.

Теперь получатель может выполнить то же соглашение, используя свой статический закрытый ключ и полученный эфемерный открытый ключ, и, наконец, расшифровать сообщение.

person Maarten Bodewes    schedule 12.12.2019
comment
Верно, так что есть дополнительный слой, который обычно скрывают libsodium и ему подобные. Попробую это сегодня и соответственно обновлю ответ! Спасибо за помощь. - person Yuri van Geffen; 13.12.2019