«Классической» Perfect Forward Secrecy в современном TLS не существует, как не существует необходимости в ней… если только вы сами не создадите ее.
Согласно классическому определению, Perfect Forward Secrecy (PFS) называется свойство протокола согласования ключа (key agreement), которое не позволит третьей стороне восстановить сеансовые ключи (session keys) с помощью добытого ею закрытого ключа (private key), пароля или иного «секрета» долговременного хранения, использованного для создания сеансовых ключей.
Это определение восходит еще к 80-м годам прошлого века, когда для согласовании ключа предполагалось непременное использование «секрета» долговременного хранения. Несмотря на определенную беззаботность, проявляемую в те дни при разработке протоколов для Интернета (кто бы мог подумать, что HTTP следует защитить не только от ошибок при передаче данных), некоторые провидцы уже тогда предполагали, что третья сторона – будь то наши доблестные разведчики или вражеские подлые шпионы – может захотеть сунуть нос в чужие электронные коммуникации, которые будут представлять для нее интерес не только в режиме реального времени, но и годы спустя.
Поскольку согласование ключа ведется по незащищенному каналу, задача сокрытия его от третьей стороны схематически решается следующим образом (например, при согласовании ключа по алгоритму RSA):
- Клиент посылает серверу свой секретный ключ, зашифрованный с помощью открытого ключа сервера (например, ключа его TLS-сертификата).
- Сервер расшифровывает секретный ключ клиента с помощью своего закрытого ключа.
- Сервер посылает клиенту свой секретный ключ, зашифрованный с помощью секретного ключа клиента.
В итоге, обе стороны могут шифровать свои сообщения друг другу секретными ключами, неизвестными третьей стороне, хотя все переговоры об их создании велись по незащищенному каналу – видит око, да зуб неймет.
Все меняется, когда эта третья сторона получает доступ к закрытому ключу сервера: если она не просто внимательно слушала, но и прилежно записывала переговоры между клиентом и сервером, обладание закрытым ключом последнего позволит ей без труда расшифровать
Чтобы этого не произошло, придумали Perfect Forward Secrecy: некоторые избыточные усилия, которые стороны защищенного обмена прилагают сегодня, чтобы их коммуникации остались защищенными от третьей стороны и завтра, когда и если
Так плавно мы приходим к правильному переводу этого термина на русский язык, который стараниями неизвестного надмозга стал «прямой секретностью» (иногда – «прогрессивной секретностью»). Forward в данном контексте означает не «прямой» и не «прогрессивный», а «будущий», как в форвардном контракте (forward contract). Т.е. Forward Secrecy – не «прямая секретность» (хотя пренебрежение ею вполне можно считать «кривой секретностью»), а «секретность в будущем», «упреждающая [возможную компрометацию «секрета»] криптостойкость».
Perfect переводят как «идеальная» или «совершенная», что в данном случае не отражает исходный смысл термина и не соответствует значению, придаваемому ему обычно в криптографии (например, «идеальная функция»).
Кристоф Гюнтер, который считается автором термина Perfect Forward Secrecy, ввел его в рамках рассмотрения достаточно сложного протокола аутентификации, предусматривающего наличие двух «секретов» – своего у каждой из сторон, да еще и третьей стороны – центра аутентификации ключей. Соответственно, «секретов» долговременного хранения было больше одного и Perfect в этом контексте означало, что утечка любого одного из них не позволит восстановить сеансовые ключи.
Оригинальное определение и его развитие
This modification restores a property of the Diffie-Hellman scheme, which we could call perfect forward secrecy: If Alice and Bob are not impersonated, when the protocol is run, finding the key Ϛ is as difficult as breaking the Diffie-Hellman scheme for every third party. We note that even the KAC could be the third party. This has the important consequence that if by accident the KAC’s secret key becomes known, the confidentiality of past message would not be compromised.
Christoph G. Günther, An Identity-Based Key-Exchange Protocol
A protocol is said to have perfect forward secrecy if compromise of long-term keys does not compromise past session keys. The idea of perfect forward secrecy (sometimes called break-backward protection) is that previous traffic is locked securely in the past. <…> If long-term secret keys are compromised, future sessions are nonetheless subject to impersonation by an active adversary. <…> Here “perfect” does not imply any properties of information-theoretic security.
Alfred J. Menezes, Paul C. van Oorschot, Scott A. Vanstone, Handbook of Applied Cryptography
Christoph G. Günther, An Identity-Based Key-Exchange Protocol
A protocol is said to have perfect forward secrecy if compromise of long-term keys does not compromise past session keys. The idea of perfect forward secrecy (sometimes called break-backward protection) is that previous traffic is locked securely in the past. <…> If long-term secret keys are compromised, future sessions are nonetheless subject to impersonation by an active adversary. <…> Here “perfect” does not imply any properties of information-theoretic security.
Alfred J. Menezes, Paul C. van Oorschot, Scott A. Vanstone, Handbook of Applied Cryptography
Необходимо также подчеркнуть, что Forward здесь не означает бесконечного будущего, т.е. принципиальной невзламываемости шифра или его конкретной реализации, постквантовой устойчивости, готовности обеих сторон коммуникаций вынести любые пытки, но не выдать «секрет» и т.д. Forward лишь обещает, что если сеансовые ключи были получены в результате применения однонаправленной функции (когда вычислить значение функции для известного аргумента значительно проще, чем вычислить аргумент по известному значению функции), то в обозримой перспективе при принятии разумных мер безопасности их не удастся восстановить методом криптографического анализа открытого ключевого материала с приемлемыми затратами.
Поэтому в реальном мире Perfect Forward Secrecy не только криптографическое, но и «административное» понятие: если третья сторона имеет неограниченный доступ к «Алисе» и «Бобу», то никакая секретность не устоит перед добросовестным терморектальным криптоанализом. Следовательно, сторонам всегда придется принимать некоторые «административные» меры, препятствующие получению «секрета» третьей стороной, не полагаясь на одну лишь криптографию.
В качестве промежуточного резюме можно сказать, что Perfect Forward Secrecy бывает только
Forward Secrecy и современный TLS
Корни упреждающей секретности уходят в прошлый век с его протоколом согласования ключа STS, где весь ключевой материал мог передаваться открытым текстом, кроме закрытой части ключа. С тех пор криптографические протоколы существенно усовершенствовались, но поскольку это свойство протокола согласования ключа, конкретный алгоритм его достижения зависит от протокола и не прописан в виде единого RFC, стандарта или иного нормативного документа.
Практические рекомендации в применении к TLS сегодня в большинстве (если не во всех) источниках сводятся к двум пунктам:
- использовать для согласования ключа только вариант алгоритма Диффи – Хеллмана с одноразовым (ephemeral) DH-ключом, то есть DHE или ECDHE;
- использовать только «достаточно стойкие» (не менее 2048 бит) и «нестандартные» (специально сгенерированные) DH-группы.
Рекомендации насколько разумные, настолько же и неполные и, более того, лишь отчасти касающиеся собственно упреждающей секретности. Для того чтобы обосновать этот тезис, вспомним принцип создания сеансовых ключей в TLS современного здорового человека, то есть TLS 1.2 или 1.3 с AEAD шифронаборами:
- Клиент и сервер генерируют по паре DH-ключей – открытый и закрытый – на оговоренной ими «основе» – конечной группе (DHE) или группе точек эллиптической кривой (ECDHE) и обмениваются своими открытыми ключами.
- Клиент и сервер вычисляют на основе своего закрытого и «партнерского» открытого ключей общий Master Secret, который у обоих сторон совпадет (Уитфилд Диффи и Мартин Хеллман гарантируют это).
- Клиент и сервер на основе общего Master Secret и своих закрытых ключей создают свои пары сеансовых ключей.
Как видно из схемы, закрытый ключ TLS-сертификата сервера для создания сеансовых ключей не используется (из чего вовсе не следует, что он теперь не нужен и его невозбранно опубликовать). Более того, вообще не используется долгоживущий ключевой материал, так что кажется, будто (EC)DHE уже обеспечивает упреждающую секретность by design.
Увы, некоторые админы старой школы, заставшие еще
Само по себе наличие буквы E в аббревиатуре DHE означает лишь, что допускается использование одноразовых DH-ключей, но не гарантируется, что они будут генерироваться сами собой, по волшебству. Явное требование использовать только одноразовые DH-ключи в (EC)DHE до сих пор находится в статусе проекта RFC.
Собственно же упреждающая секретность обеспечивается в данном случае скорее «административной» мерой – использованный ключевой материал (т.е. материал от завершенной сессии) должен (к этому мы еще вернемся) оперативно удаляться с сервера – в этом преимущество (EC)DHE перед RSA, который вынуждает хранить закрытый ключ TLS-сертификата по крайней мере до истечения срока его годности.
Что касается минимальной рекомендованной разрядности DH-группы, то она ставит под сомнение не сам алгоритм Диффи – Хеллмана, а его реализацию на конкретный момент времени. Еще вчера 1024-битные модули группы считались достаточно надежными (впрочем, они и сегодня ненадежны лишь теоретически), но с ростом вычислительных возможностей компьютеров планка поднялась до 2048 бит. Получается, что завтра 2048-битная Secrecy может оказаться уже не Forward, из чего неизбежно следует, что она не была Forward и сегодня.
Предлагаю читателям на досуге поразмышлять над этим парадоксом, а в рабочее время все же последовать данной рекомендации как разумной, просто не относящейся к упреждающей секретности, как не относится к ней, например, рекомендация использовать AES-256 вместо AES-128 при шифровании особо чувствительной информации.
«Нестандартные» DH-группы – самая дискуссионная часть рекомендации. В ее обоснование указывается, что «стандартные» группы широко применяются, поэтому являются соблазнительной целью для «взлома», поэтому рано или поздно для них создадут «радужные таблицы» (с эллиптическими кривыми это сделать куда сложнее).
Хотя с этой логикой не поспоришь, следуя ей, придется снова вернуться к мысли, что упреждающая секретность принципиально недостижима, поскольку рано или поздно все будет взломано, следовательно, и 4096-битные DH-группы – не панацея (с точки зрения упреждающей секретности).
С другой стороны, «стандартные» DH-группы хорошо изучены и (скорее всего) достаточно надежны, раз до сих пор их еще не удалось «взломать» (тогда как к ряду вполне себе рекомендуемых эллиптических кривых уже давно есть вопросы). Не стоит сбрасывать со счетов и предусмотренное RFC право на отказ клиентов от «рукопожатия» (handshake) на «нестандартных» DH-группах.
Еще одно промежуточное резюме: возможно, когда-нибудь кто-нибудь создаст таблицы предварительно вычисленных значений для «стандартных» DH-групп и начнет колоть TLS-сессии в режиме реального времени (сегодня, по оценкам, на это потребуются годы работы нескольких суперкомпьютеров для одной 1024-битной DH-группы). Возможно, когда и если это случится, мы уже давно перейдем на квантовую криптографию и достижение пока неизвестного криптоаналитика будет представлять не большую практическую ценность, чем сегодня представляет запуск Windows 11 на Nintendo Game Boy. Мнение большинства советчиков склоняется к первой вероятности, но пусть каждый решает сам.
А теперь поговорим о том, что имеет к упреждающей секретности в современном TLS самое прямое отношение, но при этом обычно остается за кадром.
Session ID, Session Tickets и 0-RTT
Протокол TLS предусматривает как полное «рукопожатие», так и краткое (а, это ты, мы уже знакомы, проходи), которое позволяет экономить ресурсы сервера (время установки соединения, процессорную мощность). Как обычно, за все хорошее приходится платить, в данном случае – новыми вызовами для упреждающей секретности.
При использовании Session ID сервер хранит ключи кэшированных сессий, возвращая в прекрасную схему (EC)DHE пресловутый «секрет» долговременного хранения. При использовании Session Tickets сервер шифрует Master Secret и другие параметры сессии, согласованные в ходе «рукопожатия», и отсылает их на хранение клиенту. Таким образом, на сервере снова хранится долгоиграющий «секрет» (ключ), но не данные (дверь), к которым он подходит. Однако, если мы допускаем возможность записи трафика третьей стороной, которая затем получит доступ к клиенту и серверу, то упреждающая секретность ставится под сомнение. Впрочем, мы уже согласились, что если третья сторона получает непосредственный доступ к нашим «Алисе» и «Бобу», под вопросом окажется любая секретность между ними.
Если от кэширования данных TLS-сессий отказаться никак нельзя (например, при кластеризации), следует ограничить время хранения кэша некоей разумной величиной, не позволяющей третьей стороне хотя бы провести слишком глубокий ретроспективный криптоанализ. Впрочем, мы снова вторгаемся в область «административной» упреждающей секретности, а там недолго углубиться в проблематику SSL termination и далее со всеми остановками, вплоть до требований к толщине стен в серверной.
В TLS 1.3 появился новый вариант компромисса между кэшированием сессий и упреждающей секретностью, названный 0-RTT (Zero-RTT, Zero Round-Trip Time). Если не вдаваться в детали, это новый, улучшенный Session ID: из ретроспективного анализа удастся восстановить только данные, переданные клиентом в ходе «рукопожатия».
В тех случаях, когда при «рукопожатии» использовался открытый ключ TLS-сертификата клиента, третьей стороне удастся получить его (в TLS 1.2 и раньше он передается в открытом виде и никого это не напрягало, на то ключ и открытый). Однако в TLS 1.3 клиент еще на стадии краткого «рукопожатия» может передать серверу полезную нагрузку, так что третья сторона сможет узнать, например, содержимое GET-запроса клиента или что еще ему не терпелось передать серверу (нагрузка после «рукопожатия» уже не будет расшифрована). Этого может быть вполне достаточно, если TLS использовался, например, для защиты DNS-запросов (DoH/DoT).
Extended Master Secret
При согласовании ключа по протоколу Диффи – Хелмана, третья сторона, лениво прослушивая трафик, узнает практически все о ключевом материале: собственно протокол, открытые ключи обоих сторон, используемую ими DH-группу и даже способ, которым стороны измываются над ней; неизвестными остаются лишь закрытые ключи и, соответственно, вычисляемые на их основе Master Secret и сеансовые ключи.
Если бы стороны использовали для согласования ключа протокол RSA, третья сторона могла встрять на этапе «рукопожатия», выдавая себя перед клиентом за сервер, а перед сервером – за клиент (атака трехстороннего рукопожатия) и приняла бы самое деятельное участие в генерации Master Secret (вернее, Pre-Master Secret, но сути это не меняет), став эдаким прокси-севером между сторонами.
Чтобы избежать вмешательства подобных «посредников», клиент и сервер должны поддерживать расширение протокола TLS – Extended Master Secret, которое меняет алгоритмы вычисления Master Secret: вместо фиксированных значений ClientRandom и ServerRandom используется хэш «рукопожатия». Таким образом, «посредник» все так же будет видеть ключевой материал, но если попытается встрять в процесс согласования, клиент и сервер получат разные значения Master Secret, и установления защищенного соединения между ними не произойдет: снова видит око, да зуб неймет.
Использование DH вместо RSA усложняет атаку трехстороннего рукопожатия, но вовсе не исключает ее: вместо относительного простого перехвата и модификации сообщений «рукопожатия», атакующему придется притворяться перед обоими сторонами не просто клиентом/сервером, а калечным клиентом/сервером, который не может в стандартные и устойчивые DH-группы, может только в строго определенный модуль («случайно» не являющийся простым числом) и вообще валяет дурака, предлагая использовать параметры DH вот точно как настоящие, не отличить (к вопросу о том, почему клиент может отказаться работать с «нестандартными» DH-группами). Extended Master Secret и тут приходит на помощь, побивая третьего лишнего
Резюме
Реальная упреждающая секретность – не криптографическое, а «крипто-административное» понятие. Все популярные реализации этого свойства протокола согласования ключа (начиная с того же STS) основаны на допущении, что некоторая часть ключевого материала ни при каких условиях не попадет к третьей стороне вследствие принятия надлежащих административных мер: надежной защиты либо оперативного уничтожения части использованного ключевого материала. Практические рекомендации по обеспечению FS в TLS сегодня таковы:
- Используйте только TLS версии не ниже 1.2.
- Используйте только AEAD шифронаборы.
- Если невозможно отказаться от ненадежных шифронаборов, задайте приоритет AEAD шифронаборов при «рукопожатии».
- DH-ключ должен быть одноразовым, т.е. заново генерироваться для каждой сессии и не храниться после создания сессионных ключей.
- Используйте DH-группы с модулем не менее 2048 бит; «стандартные» или «нестандартные» – вопрос дискутируемый.
- Используйте только стандартные и надежные эллиптические кривые – Curve25519, Curve448, NIST P-521, NIST P-384 и NIST P-256. Не забывайте, что Curve448 и NIST P-521 поддерживаются не всеми браузерами, а поддержкой NIST P-256 можно пренебречь в пользу NIST P-384.
- Поддержка Extended Master Secret для TLS 1.2 (и ниже) – обязательна.
- Если краткое «рукопожатие» не требуется, отключите поддержку Session ID, Session Tickets и 0-RTT.
- Если краткое «рукопожатие» необходимо, установите разумное время хранения информации об установленных сессиях, например, 1 час.