Почему мы отказались от RSA в пользу Ed25519 (и вам стоит тоже)
Для самохостингового TLS не нужны 4096-битные ключи RSA. Почему Bedrud перешёл на Ed25519 — и что это значит для ваших самоподписанных сертификатов.
Вы видели предупреждение браузера. «Ваше соединение не защищено.» Самоподписанные сертификаты — неизбежная реальность при самохостинге. Но ключ внутри этого сертификата важнее, чем вы думаете — а большинство туториалов до сих пор предлагают неправильное значение по умолчанию.
Привычка к RSA
Каждый гайд по самохостингу в интернете говорит одно и то же:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365RSA 4096. Потому что больше бит — больше безопасности, верно? Уже нет. Ключи RSA 4096 занимают 3,2 КБ. На VPS за $5 их генерация занимает секунды. А уровень безопасности они предоставляют примерно такой же, как 256-битный ключ на эллиптической кривой.
RSA — значение по умолчанию по исторической инерции, а не по техническим достоинствам. Он работает везде, и для сертификатов, выданных публичными CA, эта универсальная совместимость всё ещё важна. Но для самоподписанных сертификатов в стеке, который вы контролируете? Вы платите налог на производительность за совместимость, которая вам не нужна.
Что такое Ed25519
Ed25519 — схема подписи EdDSA, построенная на Curve25519. Создаёт компактные ключи фиксированного размера — 256 бит. Разработана исключительно для цифровых подписей — никакого шифрования, никакого обмена ключами, только подписи. Такая специализация делает её проще, быстрее и менее подверженной ошибкам конфигурации.
В Go — гражданин первого класса. Пакет crypto/ed25519 входит в стандартную библиотеку с Go 1.13. Генерация ключа — две строки. Сериализация через стандартный x509.MarshalPKCS8PrivateKey. Никаких внешних зависимостей, никакого CGo, никаких специальных build-тегов.
Сравнение трёх алгоритмов
| Аспект | RSA 4096 / 2048 | ECDSA P-256 | Ed25519 |
|---|---|---|---|
| Безопасность | ~112–128 бит. Зрелый, хорошо изученный. | ~128 бит. Кривая NIST. | ~128 бит. Разработан с защитой от атак по сторонним каналам. |
| Производительность | Самый медленный. Операции с большими числами. | Проверка ~10x быстрее RSA. | Самый быстрый. 30k+ подписей/сек в Go. Крошечные ключи. |
| Размер ключа | 2048 или 4096 бит. Большой на диске. | 256 бит. Компактный. | 256 бит фиксированный. Минимальный след. |
| Совместимость | Универсальная. Работает везде. | Хорошая. Все современные браузеры/клиенты. | Растущая. Полная поддержка в Go, SSH, современном TLS. |
| Формат | Стандарт PKCS#8. | PKCS#8 поверх SEC1. | PKCS#8 нативный. |
| Срок жизни ключа | Более частая ротация. | Допустим более длительный. | Как у других EC-кривых. |
| Простота в Go | Полная поддержка x509. | Риск бага KeyEncipherment (см. ниже). | Чистый. Нет опций шифрования. |
Источники: типы ключей объяснены, бенчмарки Go: RSA vs ECDSA vs Ed25519, сравнение алгоритмов SSH-ключей
Ловушка ECDSA KeyUsage
Вот баг, в который попадает почти каждый, кто переходит с RSA на ECDSA. В пакете crypto/x509 Go ключам RSA требуются и KeyUsageDigitalSignature, и KeyUsageKeyEncipherment в шаблоне сертификата. Если вы скопируете этот паттерн для ECDSA — добавите KeyUsageKeyEncipherment к EC-ключу — некоторые TLS-клиенты отклонят сертификат. EC-ключи не занимаются шифрованием ключей. Это расширение бессмысленно и активно вредно.
Вот как выглядит исправление в генерации сертификатов Bedrud (server/internal/utils/tls.go):
func keyUsageForAlgo(algo KeyAlgorithm) x509.KeyUsage {
switch algo {
case KeyRSA2048, KeyRSA4096:
return x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
default:
return x509.KeyUsageDigitalSignature
}
}Ed25519 попадает в ветку default. Чистая цифровая подпись. Нет опции KeyEncipherment, которую можно неправильно настроить. На одну ловушку меньше.
Что это значит на VPS за $5
На Hetzner CX22 (2 vCPU, 4 ГБ RAM) разница измерима:
- Генерация ключа: RSA 4096 занимает ~1–2 секунды. Ed25519 — менее 1 мс. Это важно, когда сервер генерирует самоподписанный сертификат при первой загрузке.
- TLS-рукопожатие: Ed25519 подписывает и проверяет быстрее, снижая задержку рукопожатия. На загруженном сервере с десятками WebRTC-соединений эти миллисекунды накапливаются.
- Место на диске: Приватный ключ Ed25519 — 48 байт в PEM. Ключ RSA 4096 — 3,2 КБ. Для одного сертификата разница невелика, но она отражает разницу в вычислительной сложности.
Что делает Bedrud
Bedrud генерирует самоподписанные сертификаты Ed25519 по умолчанию. Функция GenerateSelfSignedCert использует KeyEd25519, если не указано иное.
Если вам нужен другой алгоритм — для совместимости с устаревшими клиентами или по внутренним политикам — используйте флаг --key-algorithm:
bedrud run --key-algorithm rsa4096
bedrud run --key-algorithm ecdsa256Поддерживаемые значения: ed25519 (по умолчанию), ecdsa256, rsa2048, rsa4096.
Когда стоит остаться на RSA
RSA не мёртв. Он всё ещё нужен для:
- Старых Java-клиентов, не поддерживающих TLS-рукопожатие Ed25519
- Android-устройств до 7.0 (Nougat), в TLS-стеке которых нет поддержки Ed25519
- Встроенных устройств со старыми версиями OpenSSL или mbedTLS
- Корпоративных сред с промежуточными серверами инспекции TLS, понимающими только RSA
Если ваш стек современный — Go-бэкенд, браузеры на Chromium, свежие мобильные приложения — Ed25519 работает везде, где это важно.
Итог
Самохостинговая инфраструктура не должна тянуть 4096-битные RSA-ключи только потому, что туториал 2013 года так рекомендовал. Ed25519 быстрее, компактнее и менее подвержен ошибкам. Стандартная библиотека Go оптимизирована именно для него. А для самоподписанных сертификатов в контролируемом стеке аргумент совместимости RSA не выдерживает критики.
Самохостинг с лучшими значениями по умолчанию. Установите Bedrud и убедитесь сами.