Previous Entry Share Next Entry
Asymmetric encryption
victor_sudakov
Что-то непонятное мне написано в курсе CCNA про сабж.

Public key encryption is a variant of asymmetric encryption that uses a combination of a private key and a public key. The recipient gives a public key to any sender with whom the recipient wants to communicate. The sender uses a private key that is combined with the public key of the recipient to encrypt the message. Also, the sender must share its public key with the recipient. To decrypt a message, the recipient will use the public key of the sender with its own private key.

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

Или таки нужен, и как-то присутствует внутри сообщения в неявном виде?

UPD и это звучит странно:

The sender uses a private key that is combined with the public key of the recipient to encrypt the message.

Когда я отправляю кому-то PGP сообщение (только зашифрованное, не подписанное мной), то пароль от моего приватного ключа gnupg не спрашивает, значит мой приватный ключ в процессе вроде бы не участвует.

Оригинал сообщения находится по адресу https://victor-sudakov.dreamwidth.org/446749.html. Пожалуйста оставляйте комментарии там. Всего сейчас comment count unavailable комментариев.

  • 1
секретный ключ отправителя используется для цифровой подписи (т.е. что отправитель подлинный), а публичный ключ получателя - для шифрования - чтобы собственно скрыть текст

Я так же думал. Выходит у цискарей неправильно написано?

Ну никто не мешает вместо хэша - таки зашифровать секретным ключом. а может они потребность в ключе для проверки хэша так обозначили.

По хэш тут вообще не слова.

Диффи-Хельман вместо асимметричного шифрования

CCNA по этому вопросу не читал и контекста не вижу, но они явно
описывают использование алгоритма Диффи-Хельмана для передачи сообщения.

OpenPGP (по крайней мере без использования curve25519/ed25519
алгоритмов, которые ещё не стандартизованы в OpenPGP стандарте и, так
сказать, экспериментальны) подобное не использует -- поэтому описание из
CCNA не подходит под RSA, ElGamal алгоритмы там используемые. В
RSA/ElGamal действительно всё как вы описали:

    * мы знаем только публичный ключ получателя: TheirPubKey
    * генерируем сессионный (в терминах OpenPGP не знаю как точно
      называется) симметричный ключ шифрования текущего сообщения:
      K = random()
    * шифруем им сообщение M (я опущу всё что касается симметричной
      аутентификации, особенно в OpenPGP, просто зашифруем), например
      AES-ом:
      Menc = AES_Encrypt(K, M)
    * асимметрично шифруем этот сессионный ключ:
      Kenc = RSAEncrypt(TheirPubKey, K)
    * отправляем получателю зашифрованный сессионный ключ, зашифрованное
      сообщение: Kenc, Menc
    * получатель делает следующее:
      K = RSADecrypt(OurPrivKey, Kenc)
      M = AES_Decrypt(K, Menc)

это всё очевидно и в книгах по криптографии, как правило (их и не так
много выпускают современных), только подобный вариант и рассматривается.

Однако сейчас, если вы посмотрите на современные протоколы, такого не
встретить. Вместо асимметричных алгоритмов шифрования/дешифрования
используется асимметричные алгоритмы согласования ключей, для простоты
все обзываемые Диффи-Хельманом. Например framework для построения
криптографических протоколов Noise: http://noiseprotocol.org/noise.html
не имеет асимметричных функций шифрования. TLS 1.3 -- не имеет тоже.
Signal/WhatsApp -- не имеют. Наша ГОСТ криптография: http://gost.cypherpunks.ru/Russian.html
как минимум с 2001-го года (раньше просто не в курсе) не имеет
асимметричного шифрования в принципе.

Суть Диффи-Хельмана классического проста:

    * две стороны заранее договариваются о большом простом числе P и G.
      Их можно даже просто вшить в программное обеспечение как константу
    * каждая сторона генерирует большое простое число, которое будет
      называться приватным ключом: X (сторона A) и Y (сторона B)
    * число G возводится в степень приватного ключа и это будет
      обзываться публичным ключом: Apub = G^X mod P; Bpub = G^Y mod P
    * стороны пересылают друг другу свои публичные ключи и возводят
      полученный публичный ключ в степень своего приватного:
      сторона A: (G^Y)^X mod P
      сторона B: (G^X)^Y mod P
    * математика доказывает следующее:
      (G^Y)^X = mod P G^(YX) mod P
      (G^X)^Y = mod P G^(XY) mod P
       G^(YX) = mod P G^(XY) mod P
      То есть, обе стороны теперь имеют одно и то же общее вычисленное
      число. Если например взять от него хэш, то это можно использовать
      как симметричный ключ для шифрования. Злоумышленник, перехватив
      публичные ключи и зная G, P (G^X mod P и G^Y mod P) не может за
      вменяемое время вычислить либо X, либо Y и узнать общий секрет
      двух сторон. Собственно с этого алгоритма и открылась эра
      практического применения асимметричной криптографии

Возможно вы слышали про Perfect Forward Secrecy (PFS) свойства
протоколов типа TLS. Суть его в том, что компрометация долгоживущих
ключей сервера (или клиента) не скомпрометирует ранее перехваченный
трафик. Например в PGP если вы "потеряете" (выдадите) свои ключи, то все
сообщения зашифрованные на них могут быть прочтены -- PFS свойства нет.
Во многих режимах работы TLSа кроме RSA с подписями используется ещё и
Диффи-Хельман (DH) с эфемерными ключами, которые генерируются на лету и
после выработки общего ключа сразу же стираются в памяти: не зная
приватных ключей (X/Y из примера про Диффи-Хельман) вы не сможете
восстановить/"вспомнить" сессионный ключ использовавшийся для шифрования
трафика -- PFS свойство есть, утеря долгоживующего (постоянного) ключа
сервера не приведёт к возможности чтения трафика перехваченного.
Например в TLS 1.3 вообще поставили жёсткое условие: PFS режим работы
обязателен и Диффи-Хельман обязан выполнятся, никак иначе.


Re: Диффи-Хельман вместо асимметричного шифрования

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

    * вы знаете долгоживущий Диффи-Хельман ключ получателя: DHBobPub
    * генерируете эфемерную (сессионную) ключевую пару Диффи-Хельмана:
      DHAlicePriv, DHAlicePub = DHGenerate()
    * выполняете алгоритм DH для выработки сессионного симметричного
      ключа: K = DH(DHAlicePriv, DHBobPub)
      Подчеркну: как-раз именно в нём участвует *ваш* приватный и *их*
      публичный ключ. Аналогично, если сделать тоже самое на
      противоположной стороне (только с *нашим* публичным ключом и
      *ихним* приватным), то их результат работы DH() будет такой же
    * шифруете сообщение: Menc = AESEncrypt(K, M)
    * отправляете получателю: DHAlicePub, Menc
    * получатель делает следующее:
      K = DH(DHBobPriv, DHAlivePub)
      M = AESDecrypt(K, M)

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

Это здорово тем, что исчезает целый криптографический примитив. Алгоритм
согласования ключей (Диффи-Хельман) используется почти всегда (в OpenPGP
это не так, но это действительно архаичный стандарт (но не хочу сказать
что не работающий), сейчас так не делают) и поэтому можно считать что он
априори будет. А раз он есть, то бесполезным становится асимметричное
шифрование. Это всё упрощает, делает более надёжным.

Более того, если вы используете долгоживущие ключи Диффи-Хельмана, то их
можно использовать и для аутентификации собеседника, так как факт
успешного согласования ключей уже говорит о том, что противоположная
сторона знает приватный ключ. Например вы хотите аутентифицировать
сервер (Bob), зная его публичный ключ DHBobPub и хотите согласовать с
ним эфемерный ключ, для PFS свойства, чтобы компрометация DHBob ключа не
была страшна (очень грубый пример):

    * вы знаете DHBobPub
    * генерируете свою эфемерную DH пару:
      DHAliceEphPrv, DHAliceEphPub = DHGenerate()
    * подключаетесь к Bob и отсылаете свой эфемерный ключ: DHAliceEphPub
    * Bob делает следующее:
      DHBobEphPrv, DHBobEphPub = DHGenerate()
      K1 = DH(DHBobPrv, DHAliceEphPub)
      K2 = DH(DHBobEphPrv, DHAliceEphPub)
      Kencryption, Kauthentication = HASH(K1 || K2)
      Mauth = MACAuthenticate(Kauthentication, HASH(DHAliceEphPub || DHBobEphPub))
    * Bob отсылает: DHBobEphPub, Mauth
    * Alice делает следующее:
      K1 = DH(DHAliceEphPrv, DHBobPub))
      K2 = DH(DHAliceEphPrv, DHBobEphPub)
      Kencryption, Kauthentication = HASH(K1 || K2)
      MACVerify(Kauthentication, HASH(DHAliceEphPub || DHBobEphPub), Mauth)
    * Kencryption они дальше могут использовать для шифрования (как и
      Kauthentication для аутентификации сообщений)

Можно делать "тройной" Диффи-Хельман с эфемерными ключами и двумя
долгоживущими ключами для аутентификации обеих сторон. Плюс этого
подхода в том, что теперь вообще не нужна асимметричная подпись. Но
подобные протоколы конечно же можно использовать только при
online-коммуникации, так как ключи надо согласовать чтобы хотя бы одно
сообщение с полезной нагрузкой отправить. Но по факту, опять же,
протоколы типа Noise, TLS 1.3, Signal -- подписи либо не используют,
либо только для сертификатов.

Повторюсь: асимметричное шифрование сейчас не используют (если не
какая-нибудь старая система где есть только RSA например), так как нет
смысла и каких-либо плюсов, так как алгоритмы согласования ключей в
любом случае будут и они полностью заменяют в этой задаче их. OpenPGP с
curve25519 ключевой парой именно так и делает: действительно встраивает
эфемерную curve25519 Диффи-Хельман пару в сообщение. CCNA действительно
очень точно описало как используются ключевые пары. OpenPGP архаичен в
этом плане и современные системы так бы больше не делались :-)


Re: Диффи-Хельман вместо асимметричного шифрования


Re: Диффи-Хельман вместо асимметричного шифрования

Спасибо, стало намного яснее. Хотя я вижу одно преимущество "старого" подхода: можно отправить зашифрованное сообщение, не доставая свой секретный ключ вообще. Не безопаснее ли это в ряде случаев?

И в "старой" схеме с асимметричным шифрованием совсем нельзя реализовать PFS?

Re: Диффи-Хельман вместо асимметричного шифрования

Ваш *долгоживующий* (постоянный, который в ключевой паре) ключ используется только для подписи, а для шифрования будет использован эфемерный сгенерированный в памяти -- для него парольной фразы нет никакой.

В старой схеме PFS можно реализовать "костылём" в виде сгенерированных ключевых пар только для одного сообщения. Но этим *заранее* надо обменяться, поэтому в общем случае "один раз обменяться а дальше просто отправлять в один пакет в одну сторону" не получится. И, подчеркну то, что если используется Диффи-Хельман для отправки сообщения в curve25519 ключевых парах, не означает что будет PFS, так как лишь один ключ эфемерный, но ключ получателя долгоживущий.

  • 1
?

Log in

No account? Create an account