深色模式
关于密钥对
概述
公钥和私钥常被统称为密钥对。名字听起来像是一把锁配一把钥匙,但它们不是物理意义上的正反件,而是一组通过数学关系生成出来的参数。
理解密钥对,重点不在于背一堆文件头,而在于先分清:公钥能公开,私钥必须保密;它们各自负责的动作不同,但彼此对应。
什么是密钥对
密钥对通常出现在非对称密码体系里,例如 RSA、椭圆曲线相关算法。
一组密钥对包括:
- 公钥:可以公开分发
- 私钥:只能由拥有者保存
这两把钥匙不是随便配对的。一个公钥只能正确匹配它对应生成的私钥,反过来也是一样。
公钥和私钥分别做什么
在常见语境里,可以这样记:
- 公钥常用于加密或验签
- 私钥常用于解密或签名
也就是说:
- 想让别人把内容安全发给某个对象,可以公开它的公钥
- 想证明某份内容确实来自自己,要用私钥签名
这里容易混淆的一点是:同一对密钥既可以用于加解密类场景,也可以用于签名验签类场景,但具体能做哪些操作,要看算法和实现约束。
为什么公钥可以公开
公钥的设计目标,本来就是让别人能拿到它。
例如:
- 服务器把公钥相关信息放进证书,客户端才能建立安全连接
- 软件发布方公开公钥,用户才能验签安装包
如果公钥都不能发出去,非对称体系的很多优势就没了。真正必须保护的是私钥,因为私钥一旦泄露,别人就能冒充签名者,或者解开本该只属于它的内容。
RSA 密钥对长什么样
开发里最常见的并不是数学参数本体,而是序列化后的文件形式。比如 PEM 文本:
公钥:
text
-----BEGIN PUBLIC KEY-----
MIIB...
-----END PUBLIC KEY-----私钥:
text
-----BEGIN PRIVATE KEY-----
MIIE...
-----END PRIVATE KEY-----有时私钥也会写成:
text
-----BEGIN RSA PRIVATE KEY-----
MIIE...
-----END RSA PRIVATE KEY-----这些头部文字不是装饰,而是在提示内容对象和封装方式。
PKCS#1、PKCS#8 和 PEM 是什么关系
这几个词常被混用,最好拆开看:
PEM:一种文本编码表示方式PKCS#1:RSA私钥和公钥相关结构的一种定义PKCS#8:私钥的通用封装格式,不只给RSA用
因此:
BEGIN RSA PRIVATE KEY常见于PKCS#1BEGIN PRIVATE KEY常见于PKCS#8
两者都可能用 PEM 文本保存。也就是说,PEM 说的是“怎么写出来”,PKCS#1 和 PKCS#8 说的是“里面按什么结构组织”。
公钥是不是能从私钥推出来
通常可以。
私钥里包含的信息比公钥更多,所以很多工具都支持从私钥导出公钥。反过来则不行,至少在设计目标上就是不该行。
这也是为什么很多系统里只需要备份私钥文件,公钥可以随时重新导出。
开发里最常见的几种文件
| 文件类型 | 常见后缀 | 典型内容 |
|---|---|---|
| 公钥 | .pem .pub | 公钥 |
| 私钥 | .key .pem | 私钥 |
| 证书 | .crt .cer .pem | 公钥 + 身份信息 + CA 签名 |
| 证书包 | .p12 .pfx | 证书 + 私钥 + 证书链 |
证书不是公钥文件的简单别名,它比裸公钥多了一层身份和签发关系。
使用密钥对时最重要的原则
最重要的一条其实很朴素:私钥不能泄露。
其次还有几条工程上很实用:
- 不要把私钥提交到代码仓库
- 不要把测试私钥和生产私钥混用
- 不要只看文件后缀判断内容,最好看头部或直接用工具解析
- 生成密钥时优先使用当前仍被认可的算法和长度
密钥对本身不复杂,复杂的是围绕它的分发、存储、权限和生命周期管理。
