Security

PFS

PFS (Perfect Forward Secrecy) — свойство протокола, при котором компрометация долговременного ключа не позволяет расшифровать ранее записанные сессии.

Что такое PFS

PFS расшифровывается как Perfect Forward Secrecy — «совершенная прямая секретность» (по-русски встречается «пфс», а в современных RFC чаще пишут просто forward secrecy, без «perfect»). Это свойство криптографического протокола: компрометация долговременного приватного ключа сервера не даёт расшифровать сессии, записанные ранее.

Проблема, которую PFS решает, называется «Store Now, Decrypt Later» — «запиши сейчас, расшифруй потом». Представьте протокол без PFS: сеансовый ключ шифруется публичным ключом сервера из сертификата и в таком виде передаётся. Атакующий годами пишет ваш трафик, не в силах его прочитать. Через три года он получает приватный ключ сервера — украл, изъял по решению суда, купил у админа, дождался уязвимости уровня Heartbleed. И тогда он расшифровывает весь архив за все годы разом. Одна утечка одного файла обесценивает всю историю переписки задним числом.

С PFS этот сценарий не работает. Даже с приватным ключом на руках атакующий не получает ничего: старые сессии остаются нечитаемыми навсегда.

Как это работает

Секрет в эфемерных ключах. Вместо того чтобы передавать сеансовый ключ, стороны вычисляют его независимо друг от друга по протоколу Диффи-Хеллмана:

  1. На каждое соединение генерируется новая одноразовая пара ключей.
  2. Стороны обмениваются публичными частями и каждая вычисляет общий секрет у себя. По сети общий секрет не передаётся ни в каком виде — даже зашифрованным.
  3. Долговременный ключ сервера используется только чтобы подписать обмен (доказать, что это действительно ваш сервер), а не чтобы зашифровать секрет.
  4. После завершения сессии эфемерные ключи выбрасываются из памяти.

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

Буква E в названии шифров — от ephemeral, и именно она означает наличие PFS:

Обмен ключами PFS Комментарий
RSA (статический) Нет Ключ шифруется сертификатом. Удалён из TLS 1.3
DHE Есть Классический эфемерный Диффи-Хеллман, медленный
ECDHEЕсть На эллиптических кривых, быстрый — сегодняшний стандарт

Практика

В TLS 1.3 forward secrecy обязателен: статический RSA-обмен вычищен из протокола, все режимы — (EC)DHE. Ничего настраивать не нужно, PFS есть по факту использования версии.

В TLS 1.2 он опционален, поэтому шифры выбирают явно:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

Проверить, что PFS реально работает:

openssl s_client -connect example.com:443 </dev/null 2>/dev/null | grep -i 'cipher\|temp key'
# Cipher    : TLS_AES_256_GCM_SHA384
# Server Temp Key: X25519, 253 bits   ← строка Temp Key = PFS есть

Главная ловушка — session tickets. Механизм возобновления сессий (RFC 5077) шифрует состояние сессии ключом сервера и отдаёт клиенту тикет. Если этот ключ долгоживущий и не ротируется, он становится ровно тем самым долговременным секретом, от которого PFS должен был избавить: утёк ключ тикетов — расшифровались все возобновлённые сессии. Nginx по умолчанию генерирует ключ при старте и не меняет его до перезапуска, а в кластере за балансировщиком его ещё и приходится синхронизировать между узлами. Простое решение — ssl_session_tickets off;, правильное для высоконагруженных систем — регулярная ротация ключей.

Где ещё встречается

PFS — не только про TLS. IPsec/IKEv2 в VPN поддерживает PFS в фазе 2 и его стоит включать явно. WireGuard даёт forward secrecy по умолчанию через регулярную смену ключей. В мессенджерах Signal Protocol идёт дальше и меняет ключи на каждое сообщение — компрометация ключа не раскрывает даже соседние сообщения в том же диалоге.

Отдельный аргумент за PFS сегодня — постквантовая перспектива: трафик, записанный сейчас, могут попытаться расшифровать через десятилетия. Forward secrecy не решает эту задачу целиком, но снимает самый дешёвый вектор — кражу ключа сервера.

Связанные термины

Готовы запустить GPU-задачу?

Запустить GPU-сервер