Skip to content

免费在线 RSA 密钥对生成器 — ECDSA、Ed25519

在线生成 RSA 密钥对,私钥不离开浏览器。支持 RSA 2048/4096、ECDSA、Ed25519,可导出 PKCS#8 与 PKCS#1 PEM。

无追踪 浏览器中运行 免费
密钥对在你的浏览器里用 Web Crypto API 生成,生成过程不发出任何网络请求。断开网络,本页照样能用。

PKCS#8(BEGIN PRIVATE KEY)是现代默认格式,也是 JDK 期待的格式。PKCS#1(BEGIN RSA PRIVATE KEY)是 OpenSSL 的传统形式,仍有部分网关只认它。切换只是把同一把密钥重新编码。

请妥善保密。任何拿到它的人都能冒充你。

公钥指纹 — SPKI DER 的 SHA-256
JWK(JSON Web Key)
私钥 JWK — 这一份绝不能公开
 
公钥 JWK
 

用 OpenSSL 生成同类密钥对

已就 RFC 5958/5208(PKCS#8)、RFC 8017(PKCS#1)、RFC 8410(Ed25519)与 RFC 7468 PEM 编码的正确性,以及 Web Crypto API 在 RSA、ECDSA 和 Ed25519 上的行为进行审阅。 — Go Tools 安全工具团队 · 2026年8月10日

我们的团队把 PKCS#8 到 PKCS#1 的转换逐字节对照 Node crypto 模块的参考输出做过校验,因此在这里导出的密钥,与 OpenSSL 用同样材料生成的密钥完全一致。

什么是 RSA 密钥生成器?

RSA 密钥生成器产出一对在数学上互相绑定的密钥:私钥你自己留着,公钥拿去分发。用私钥签过的东西可以用公钥验证,而只有公钥这一半适合公开。这种不对称正是全部意义所在——它让验签方能够校验你的签名,却拿不到伪造签名的能力,而共享密钥永远给不了这一点。

本生成器通过 Web Crypto API 在你的浏览器里运行,因此私钥是在标签页内创建的,生成过程不发出任何网络请求。除 RSA 之外,它还能生成 ECDSA 和 Ed25519 密钥对——用途相同,密钥却短得多:Ed25519 私钥在 PKCS#8 下是 48 字节,而一把 2048 位的 RSA 密钥要超过 1.2 KB。

真正让人栽跟头的不是数学,而是包装。同一把密钥可以写成 PKCS#8、PKCS#1、SPKI 或 JWK,而拒收其中一种的库往往会接受另一种,给出的提示却不比一句解析错误更清楚。下面的表格把每种容器对应到期待它的生态。

// Verify a downloaded key pair matches, using OpenSSL:
openssl pkey -in rsa-2048-private.pem -pubout | diff - rsa-2048-public.pem
// No output means the public key really belongs to that private key.

核心功能

在你的浏览器里生成

密钥来自你自己标签页里的 Web Crypto API,生成过程不发出任何网络请求。断开连接它照样能用,这说明这个工具办事不需要服务器。

RSA、ECDSA 与 Ed25519

RSA 2048、3072 和 4096;ECDSA 的 P-256、P-384 和 P-521;以及 Ed25519,同一个页面、同一套导出选项。

PKCS#8 与 PKCS#1 输出

无需动 OpenSSL 即可在 BEGIN PRIVATE KEY 与传统的 BEGIN RSA PRIVATE KEY 之间切换。这个开关只是把屏幕上已有的密钥重新编码,所以它始终是同一把密钥。

JWK 导出

两半密钥都提供 JSON Web Key 形式。进 JWKS 文档或 JOSE 验签方的是公钥 JWK;私钥 JWK 只归你的签名端所有,绝不能公开。

SHA-256 指纹

每对密钥都附带其公钥的指纹,方便你在带外确认双方持有的是同一把密钥。

配套的 OpenSSL 命令

输出区下方会给出在本地生成同类密钥的等效命令,你随时可以转到命令行继续。

文件名一目了然的下载

文件按 rsa-2048-private.pem 和 rsa-2048-public.pem 保存,而不是一个还得你手动改名的通用文件名。

无需账号,没有配额

整个过程不涉及服务器,因此没有什么可注册的,也没有用完就停的额度。

实战示例

完整展示一对 Ed25519 密钥

Algorithm: Ed25519
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIA2HJVU1qChbOJN8XksXVhyD0IjYVt0UU6Mwz814rOFf
-----END PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAV5uB7UaPJrtncx3SXNtNzn1ZXjF1ApwvzBZ8nFzT5eU=
-----END PUBLIC KEY-----

Ed25519 的私钥在 PKCS#8 下是 48 字节,公钥是 44 字节,所以两段 PEM 各自只有一行 base64。这里展示的是一次性演示用的密钥对——请自己生成一对,不要照抄。

PKCS#8 与 PKCS#1 的头部差异

Algorithm: RSA 2048, structure toggled
PKCS#8:  -----BEGIN PRIVATE KEY-----
PKCS#1:  -----BEGIN RSA PRIVATE KEY-----

同一把密钥,两层包装。PKCS#8 在 RSA 结构外面加了一个算法标识符,所以它能通吃所有算法,而 PKCS#1 只为 RSA 而存在。拨动开关只是把屏幕上已有的密钥重新编码,因此指纹不会变。

RSA 2048 公钥

Algorithm: RSA 2048
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtuvUHLjyK9zje2aaNIni
eSccN1uleXFRBb1g2TN6bk/fbpPCGDyh71m73oB9Bk8+fKVkSThXyWTtpgblB7pX
iQBtTvSWVZGHprkLgMGkU2Yw8Z43m1WpoRuYyXNFe92S5viIdVuKTj/VEUuEpzHd
ffWMIUw70LaUdTP04iQdkNVeS3M6VHkpTwsPSQfsFSwObtLVNy2Lf+ODwJRqCk2r
C749hgKqBdJqkcIj49R7UP4SMQ/9V3yy8DFMrIcgsjC4tHwlQSCGeXNxTNlapGSa
ke55LUR83FASryVJRbUs678SCZSFkyGcT0qLZ/olu/e7Jj2lB0Qy/SJawkrs9hPE
4QIDAQAB
-----END PUBLIC KEY-----

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 这段前缀就是 rsaEncryption 算法标识符,看一眼开头就能认出这是一把 RSA 的 SPKI 公钥。

以 JWK 表示的公钥

Algorithm: Ed25519, JWK panel
{
  "key_ops": [
    "verify"
  ],
  "ext": true,
  "alg": "Ed25519",
  "crv": "Ed25519",
  "x": "V5uB7UaPJrtncx3SXNtNzn1ZXjF1ApwvzBZ8nFzT5eU",
  "kty": "OKP"
}

这是原样导出的结果,连 Web Crypto 总会加上的 key_ops 和 ext 成员也在内。JWKS 条目并不需要它们——把两个都删掉,改为加上 kid 和 use,验签方才能在轮换期间挑对密钥。Ed25519 归入 OKP 密钥类型;RSA 密钥则是 kty 为 RSA,并带 n 和 e 两个成员。

SHA-256 指纹

Algorithm: Ed25519
SHA256(SPKI) = KAXVxapxpG4zLsTVMpPafovT+X1NLWc8fsOXqtrb59o=

这是对公钥结构做的 SHA-256 摘要,短到可以在电话里念出来。注意它不是 ssh-keygen 打印的那个值——OpenSSH 摘要的是它自己的线格式,所以同一把密钥的两个值永远对不上。

如何使用 RSA 密钥生成器

  1. 1

    选择算法

    RSA 兼容的老系统最多。ECDSA 用短得多的密钥换来同等强度。Ed25519 是新签名场景的现代默认选择。

  2. 2

    选择密钥长度

    RSA 2048 满足当前的合规要求;3072 和 4096 为长期使用的密钥留出裕度。ECDSA 可选 P-256、P-384 和 P-521。Ed25519 只有一个固定长度。

  3. 3

    选择 PEM 结构

    PKCS#8 输出 BEGIN PRIVATE KEY,几乎处处可用,JDK 也在其列。只有当某个系统明确要 BEGIN RSA PRIVATE KEY 时,才切到 PKCS#1。

  4. 4

    复制或下载两半密钥

    私钥存进你的密钥管理器,公钥交给需要验签的一方。私钥这一半绝不要发给任何人。

  5. 5

    核对指纹

    通过另一条通道比对 SHA-256 指纹,确认对方装上的确实是你这边生成的那把公钥。

常见的密钥格式错误

把公钥粘到了该放私钥的位置

签名要用的是私钥那一半。当一个库拿到 BEGIN PUBLIC KEY 而它期待的是私钥时,通常只会报一个毫无帮助的解析错误,不会说破真正的问题。

✗ 错误
-----BEGIN PUBLIC KEY-----
✓ 正确
-----BEGIN PRIVATE KEY-----

PEM 结构与库不匹配

只有少数几个生态只读传统的 RSA 布局——OpenSSL 自己的 -traditional 输出、部分支付网关 SDK、较老的 Ruby 与 Perl 工具。多数现代库、尤其是 JDK,期待的是 PKCS#8。直接切换 PEM 结构开关,别去翻转换命令。

✗ 错误
-----BEGIN RSA PRIVATE KEY-----
✓ 正确
-----BEGIN PRIVATE KEY-----

丢掉了末尾的换行

PEM 文件在最后一行分隔符之后带一个换行。经过会裁掉空白的表单字段复制,得到的文件会被某些解析器直接拒绝——而由于缺的那个字符是看不见的,文件在编辑器里看起来完全正常。

✗ 错误
-----END PRIVATE KEY-----[EOF]
✓ 正确
-----END PRIVATE KEY-----↵[EOF]

有个字符在传输途中丢了

破坏一段 PEM 的是丢失、插入或替换掉的字符,而不是行宽——多数解析器接受任意换行方式。经由聊天软件或表单字段的一次复制,可能悄悄把一个换行变成空格,而 base64 不会提示是哪个字符出了问题,密钥只会加载失败。请用复制按钮,别用鼠标手动划选。

✗ 错误
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtuvUHLjyK9zje2aaNIni eSccN1uleXFRBb1g2TN6bk
✓ 正确
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtuvUHLjyK9zje2aaNIni
eSccN1uleXFRBb1g2TN6bk

配置的是 RS256 却给了 HS256 的密钥

HS256 用一个共享密钥;RS256 用一对密钥。把一串随机字符喂给 RS256 签名器,会在解析这一步就失败。要么在这里生成密钥对,要么——如果你本意就是 HS256——用我们的 JWT 密钥生成器

✗ 错误
alg: RS256, key: 8f3a9c2e1b7d
✓ 正确
alg: RS256, key: -----BEGIN PRIVATE KEY-----

把 PEM 粘进了 authorized_keys

SSH 公钥是 OpenSSH 那种单行的 ssh-ed25519 AAAA… 格式,不是 PEM 块,所以把本页的公钥粘进 authorized_keys 是不会生效的。如果是 RSA 密钥,你可以在本地用 ssh-keygen -y 导出正确的那一行;而就 SSH 登录本身而言,直接在目标机器上生成还是更好的做法。

✗ 错误
-----BEGIN PUBLIC KEY-----
✓ 正确
ssh-keygen -y -f rsa-2048-private.pem > id_rsa.pub

谁在使用本工具

用 RS256 或 EdDSA 签发 JWT
非对称的 JWT 算法需要的是密钥对而非共享密钥。用私钥签名、公开公钥,验签方手里就没有任何能凭空铸造令牌的东西。我们的 JWT 编码器 可以直接吃本页产出的密钥。
为 webhook 和发布产物签名
公钥只需公布一次,之后每个载荷都用私钥签名,消费方无需任何会泄露的共享凭证就能验证真伪。
本地开发与测试
要跑签名验证的测试套件需要一对一次性密钥。在这里生成一对,比回想 OpenSSL 那串参数更快。
搞清楚一对密钥长什么样
把不同算法和 PEM 结构并排切着看,差异会变得很具体——这是读规范文档给不了的。
准备 JWKS 端点
公钥 JWK 可以直接塞进 OpenID Connect 发现文档的 keys 数组。记得加上 kid,好让验签方在轮换期间挑得出它,并把私钥 JWK 挡在这份文件之外。
从 RSA 迁移走
在 RSA 原件旁边生成对应的 Ed25519 替代品,先把体积差异看清楚再决定是否切换。
修一个格式不匹配的问题
当某个库以解析错误拒绝一把密钥时,改用另一种 PEM 结构重新导出,往往就是全部的修复动作。

PEM 格式与生成器的工作原理

哪种容器用在哪里
一把密钥,五种包装。挑错容器是密钥被拒收的头号原因,而错误信息通常不会比一句解析失败更具体。
容器PEM 头部装什么在哪里会遇到
PKCS#8BEGIN PRIVATE KEY任意算法Web Crypto、JDK、Go、.NET——多数现代库
PKCS#1BEGIN RSA PRIVATE KEY仅 RSAOpenSSL 的传统输出、部分支付网关、较老的 Ruby 与 Perl 工具
SPKI / X.509BEGIN PUBLIC KEY任意算法,公钥这一半几乎每个库期待的公钥形式
PKCS#1 publicBEGIN RSA PUBLIC KEY仅 RSA,公钥这一半老旧的 RSA 工具
JWK无——它是 JSON任意算法JWKS 端点、OIDC 发现文档、JOSE 库
要转换你手上已有的文件,openssl pkcs8 -topk8 -nocrypt -in pkcs1.pem -out pkcs8.pem 走一个方向,openssl rsa -traditional -in pkcs8.pem -out pkcs1.pem 走另一个方向。
随机数来自操作系统
Web Crypto 的密钥生成种子取自平台的熵源——Linux 上是 getrandom,Windows 和 macOS 上则是各自的系统 CSPRNG。这与 OpenSSL 取用的是同一类源,而不是 JavaScript 的伪随机数生成器。
生成过程不会冻住页面
crypto.subtle.generateKey 是异步的,而在主流浏览器引擎中,寻找素数的过程发生在主线程之外,因此在搜索一个 4096 位模数期间界面依然响应。页面无论如何都会显示一个转圈提示,因为这次搜索要花多久全看运气。
PKCS#8 包着 PKCS#1
一个 PKCS#8 的 PrivateKeyInfo 由版本号、算法标识符和一个 OCTET STRING 组成。对未加密的 rsaEncryption 密钥而言,那个 OCTET STRING 里装的正是完整的 PKCS#1 RSAPrivateKey——本页就是靠这一点在两种结构间转换的,无需重新推导任何参数。
公钥使用 SubjectPublicKeyInfo
BEGIN PUBLIC KEY 是 X.509 的 SubjectPublicKeyInfo:一个算法标识符加一个 BIT STRING。这串比特里装什么取决于算法——RSA 装的是 PKCS#1 的 RSAPublicKey,这也是 BEGIN RSA PUBLIC KEY 更短的原因;ECDSA 装的是未压缩的曲线点,Ed25519 装的则是那 32 字节的原始密钥。
公钥指数固定为 65537
这里的每一把 RSA 密钥都使用 e = 65537,写作 0x010001。它足够大,可以避开小指数攻击;而二进制里只有两个 1,因此一次验签只需 16 次平方加一次乘法。
指纹摘要的是 DER 而非 PEM
SHA-256 指纹是对二进制的 SubjectPublicKeyInfo 计算的。如果改为对 base64 文本做摘要,换行方式一变指纹就跟着变了。在本地的等效做法是 openssl pkey -in private.pem -pubout -outform DER | openssl dgst -sha256 -binary | openssl base64

密钥管理最佳实践

在密钥要用的地方生成它
一把在网络上走过的私钥,等于向沿途每一跳都暴露过。在浏览器里生成能让密钥本身不上网,尽管页面自身的代码仍是经由网络送达的;直接在目标主机上生成,则连拷贝这一步都省了。要保护生产系统的密钥,请优先选择在主机上生成。
除非有硬性要求,否则优先 Ed25519
Ed25519 用 32 字节的密钥提供强安全性,签名快,也没有会配错的参数可选。只有当对方系统或某个老库让你别无选择时,才回头用 RSA。
把 2048 位当作下限
NIST SP 800-131A 自 2013 年起已禁止用低于 2048 位的 RSA 生成签名,公共证书颁发机构也不会为更短的密钥签发证书。预期要服役很多年的密钥,请选 3072 或 4096。
绝不把私钥提交进仓库
私钥应放进密钥管理器,或放进运行时才加载的环境变量。一旦某把密钥进了代码仓库,轮换是唯一安全的应对。
按计划轮换,而不是只在出事后才轮换
先带着密钥 ID 发布新公钥,再下线旧的,验签方就能在重叠期内同时接受两把。平时练熟的轮换,才是压力之下能用的轮换。

常见问题

在网站上生成私钥安全吗?
密钥由你自己浏览器里的 Web Crypto API 生成,本页在生成过程中不发出任何网络请求——你可以盯着网络面板看,或者干脆断网,会发现生成照样能跑。但要说清楚这能证明什么、不能证明什么:它说明本页办事不需要服务器,却不能证明脚本没被做过手脚,因为这段 JavaScript 每次访问都会从我们的服务器重新取回。真正留下的风险属于浏览器而非网络——恶意扩展能读到页面内容和你的剪贴板,能碰到这台机器的人也能读走下载下来的文件。要保护生产系统的密钥,请在将要使用它的那台主机上生成;下面的 OpenSSL 命令做的正是这件事。本页适合开发、测试、学习,以及任何可以接受浏览器生成密钥的场合。
PKCS#8 和 PKCS#1 有什么区别?
它们是同一把 RSA 密钥的两种容器。PKCS#1 的标记是 BEGIN RSA PRIVATE KEY,直接装 RSA 的那几个大数,且只为 RSA 而存在。PKCS#8 的标记是 BEGIN PRIVATE KEY,在同样这些数外面裹了一个算法标识符,因此同一种格式能同时承载 RSA、ECDSA 和 Ed25519。多数现代库期待 PKCS#8——尤其值得一提的是,JDK 不额外引库就只读 PKCS#8——而不少支付网关和 OpenSSL 时代的老工具仍然要求 PKCS#1。切换本页的开关只是把屏幕上已有的密钥重新编码,因此既不会增加也不会丢失任何信息,指纹也保持不变。
如何把 PKCS#1 密钥转成 PKCS#8,或者转回去?
拨动本页的 PEM 结构开关,同一把密钥就会以另一种容器重新输出。对于你手上已有的文件,OpenSSL 可以在本地转换:openssl pkcs8 -topk8 -nocrypt -in pkcs1.pem -out pkcs8.pem 把 BEGIN RSA PRIVATE KEY 的文件变成 BEGIN PRIVATE KEY,而 openssl rsa -traditional -in pkcs8.pem -out pkcs1.pem 则走相反方向。两个方向都不会增删任何密钥材料,变的只是外面那层包装——这正是两个文件描述的是同一把密钥、算出的指纹也完全相同的原因。
怎么从 RSA 私钥得到公钥?
公钥可以从私钥推导出来,反过来永远不行。本页会同时显示两半,所以没有什么需要你去推导。如果私钥文件已经在你的磁盘上,openssl pkey -in private.pem -pubout -out public.pem 会写出配对的 BEGIN PUBLIC KEY 文件。这也是检验一对密钥是否配套的办法——把公钥这一半重新导出来,与别人给你的那份比对一下就知道了。
该选 RSA 还是 Ed25519?
没有外力逼你时就选 Ed25519。它用 32 字节的密钥达到与 RSA 3072 相当的安全强度,签名更快,也没有会配错的参数。当对方系统、证书颁发机构或某个老库要求 RSA 时就选 RSA——这在企业和支付系统里仍然常见。ECDSA 介于两者之间,在 TLS 里得到广泛支持。
2048 位的 RSA 现在还够用吗?
对今天的大多数用途来说够用。NIST 把 2048 位 RSA 评为 112 位安全强度,并在 SP 800-57 中把它带到 2030 年;3072 位达到 128 位强度,也是 NIST 为此后所指向的级别。所以:几年内就会轮换的密钥用 2048,预期到 2030 年代仍在服役、或证书颁发机构有硬性要求的密钥用 3072 或 4096。更长密钥的代价是签名更慢、签名更大,而不是安全性更弱。
这些密钥能用来签 JWT 吗?
可以。RSA 密钥适用于 RS256、RS384、RS512 以及对应的 PSS 变体;ECDSA 的 P-256 对应 ES256;Ed25519 就是 EdDSA 算法。用私钥签名、公开公钥,验签方就只能校验签名而无法创建签名。如果你用的是 JWK 面板而非 PEM,有一点要注意:Web Crypto 会给 RSA 的 JWK 打上 alg 为 RS256,严格的库会因此拒绝把它用于 PS256 或 RS512——删掉 alg 成员,或者干脆用 PEM。我们的 JWT 编码器 可以直接使用这些密钥,JWT 解码器 则能看到签出的令牌里到底装了什么。
这里能生成 SSH 密钥吗?
不能直接生成。OpenSSH 自己的私钥文件是另一种容器,本页不写那种格式。不过这里的 RSA 密钥仍然可用:ssh-keygen -y -f rsa-2048-private.pem > id_rsa.pub 就能从你下载的文件推导出 authorized_keys 那一行。这里的 Ed25519 密钥则不行,因为 OpenSSH 不接受 PKCS#8 形式。就 SSH 登录而言,更好的答案依然是在需要这把密钥的机器上运行 ssh-keygen -t ed25519,这样根本不必搬运私钥。而对于 JWT 签名、CI 发布签名和 webhook 验证,本页产出的 PKCS#8 密钥正是那些工具想要的。
可以给私钥加口令保护吗?
这里不行。加密的 PKCS#8 需要一个 Web Crypto API 并未暴露的密钥派生步骤,实现它就意味着在 JavaScript 里手搓密码学。请改在本地加口令:openssl pkcs8 -topk8 -in private.pem -out encrypted.pem 会读取你下载的文件并提示你输入口令。
指纹是用来做什么的?
它是对公钥结构做的 SHA-256 摘要,短到可以用语音或聊天消息比对。当你把一把公钥发给别人时,通过另一条通道核对指纹,就能确认对方收到的就是你发出的那把。它只标识公钥,不会泄露私钥那一半的任何信息。注意它不是 ssh-keygen -l 打印的那个数:OpenSSH 摘要的是它自己的线格式而非 SPKI 结构,所以同一把密钥的两个值永远对不上。