返回博客

为什么我们放弃了 RSA 转向 Ed25519(你也应该这样做)

自托管 TLS 不需要 4096 位 RSA 密钥。以下是 Bedrud 切换到 Ed25519 的原因——以及这对你的自签名证书意味着什么。

2026年5月12日 Bedrud 团队 engineering, security, self-hosting

你一定见过浏览器的警告。“您的连接不是安全的。“自签名证书是自托管时的常见现象。但证书里的密钥比你想象的更重要——而大多数教程仍然给了你错误的默认选择。

RSA 的惯性

互联网上每一篇自托管指南都写着同样的命令:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

RSA 4096。因为数字越大越安全,对吧?已经不是了。RSA 4096 密钥有 3.2 KB。在一台 5 美元的 VPS 上生成需要好几秒。而它提供的安全级别大约等同于一个 256 位的椭圆曲线密钥。

RSA 成为默认选择是因为历史惯性,而不是技术优势。它确实到处都能用,对于公共 CA 签发的证书,这种通用兼容性仍然重要。但对于你自己控制的栈中的自签名证书呢?你在为不需要的兼容性付出性能代价。

Ed25519 简介

Ed25519 是基于 Curve25519 的 EdDSA 签名方案。它生成固定大小的 256 位密钥,体积小巧。专为数字签名设计——不做加密,不做密钥交换,只做签名。这种专注意味着更简单、更快、更不容易出错。

在 Go 中,Ed25519 是一等公民。crypto/ed25519 包从 Go 1.13 起就在标准库中。密钥生成只需两行代码。序列化使用标准的 x509.MarshalPKCS8PrivateKey。无需外部依赖,无需 CGo,无需特殊构建标签。

三方对比

方面RSA 4096 / 2048ECDSA P-256Ed25519
安全性~112–128 位。成熟,研究充分。~128 位。NIST 曲线。~128 位。专为抵抗侧信道攻击而设计。
性能最慢。大数运算。验证速度约为 RSA 的 10 倍。最快。Go 中每秒 30k+ 次签名。密钥极小。
密钥大小2048 或 4096 位。磁盘占用大。256 位。紧凑。256 位固定。最小占用。
兼容性通用。所有平台都支持。良好。所有现代浏览器/客户端。增长中。Go、SSH、现代 TLS 完全支持。
格式PKCS#8 标准。PKCS#8 over SEC1。PKCS#8 原生。
密钥寿命需要更频繁轮换。可接受更长时间。与其他 EC 曲线相同。
Go 易用性完整 x509 支持。KeyEncipherment bug 风险(见下文)。纯净。无加密选项。

来源:密钥类型详解Go 基准测试:RSA vs ECDSA vs Ed25519SSH 密钥算法对比

ECDSA KeyUsage 陷阱

这是一个几乎每个从 RSA 切换到 ECDSA 的人都会踩的坑。在 Go 的 crypto/x509 中,RSA 密钥在证书模板中需要同时设置 KeyUsageDigitalSignatureKeyUsageKeyEncipherment。如果你把这个模式照搬到 ECDSA 上——给 EC 密钥加上 KeyUsageKeyEncipherment——一些 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 选项可供误配。少一个坑。

在 5 美元 VPS 上的实际影响

在 Hetzner CX22(2 vCPU,4 GB RAM)上,差异是可测量的:

  • 密钥生成:RSA 4096 需要 ~1–2 秒。Ed25519 不到 1 毫秒。当服务器在首次启动时生成自签名证书,这很重要。
  • TLS 握手:Ed25519 签名和验证更快,减少了握手延迟。在一个处理数十个 WebRTC 连接的繁忙服务器上,这些毫秒会累积。
  • 磁盘占用:Ed25519 私钥 PEM 编码后仅 48 字节。RSA 4096 密钥 3.2 KB。对单个证书来说不算什么,但反映了计算复杂度的差异。

Bedrud 的做法

Bedrud 现在默认生成 Ed25519 自签名证书。GenerateSelfSignedCert 函数使用 KeyEd25519,除非你指定其他算法。

如果你需要不同的算法——用于旧客户端兼容性或内部策略——使用 --key-algorithm 选项:

bedrud run --key-algorithm rsa4096
bedrud run --key-algorithm ecdsa256

支持值:ed25519(默认)、ecdsa256rsa2048rsa4096

什么时候应该继续使用 RSA

RSA 没有消亡。以下场景仍需要它:

  • 旧版 Java 客户端,不支持 Ed25519 TLS 握手
  • Android 7.0 之前的设备(Nougat),TLS 栈中缺少 Ed25519 支持
  • 嵌入式设备,运行旧版 OpenSSL 或 mbedTLS
  • 企业环境,使用只识别 RSA 的 TLS 检测中间件

如果你的技术栈是现代的——Go 后端、Chromium 系浏览器、较新的移动应用——Ed25519 在所有重要的地方都能正常工作。

总结

自托管基础设施不应该仅仅因为 2013 年的教程推荐就背负 4096 位 RSA 密钥。Ed25519 更快、更小、更不容易出错。Go 标准库正是为它优化的。对于受控栈中的自签名证书,RSA 的兼容性论点站不住脚。

用更好的默认值进行自托管。安装 Bedrud,亲自试试。