在开发过程中,传递公钥的常见格式主要有 PEM(文本格式)、DER(二进制格式)、Base64(纯编码字符串) 和 SSH公钥格式。以下是同一对 RSA 公私钥(示例密钥参数:n=0xB57B...
, e=0x10001
)在不同格式下的示例对比:
公钥格式对照表(同一密钥对)
格式类型 | 示例 | 结构说明 | 代码传递注意事项 |
---|---|---|---|
PEM 格式 | -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1e441MQyXuCK1VQWorLOrqEKa ...(Base64 内容)... -----END PUBLIC KEY----- | 包含头尾标记的文本格式,内容为 Base64 编码的 DER 数据 | 需保留完整文本(含头尾),可直接作为字符串传递 |
DER 格式 | 30 81 9F 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 81 8D 00 30 81 89 02 81 81 00 B5 7B 8E... | 二进制格式,无头尾标记,直接存储 ASN.1 编码的密钥数据 | 需以字节数组(byte[] )或二进制文件传递 |
Base64 编码 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1e441MQyXuCK1VQWorLOrqEKa...(同PEM中间部分)... | 仅提取 PEM 中的 Base64 部分(不含头尾和换行) | 作为纯字符串传递,需在代码中解码为二进制后再使用 |
SSH 公钥格式 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1e441MQyXuCK1VQWorLOrqEKa...(Base64)... user@example.com | 包含算法前缀(ssh-rsa )、Base64 编码的公钥数据、注释 | 需完整传递字符串,常用于 SSH 登录或 Git 认证场景 |
关键说明
-
PEM vs Base64
- PEM = Base64 内容 + 头尾标记(
-----BEGIN PUBLIC KEY-----
)。 - Base64 是 PEM 的核心编码,单独使用时需手动去除头尾。
- PEM = Base64 内容 + 头尾标记(
-
DER 的二进制特性
- DER 是 ASN.1 标准的二进制编码,体积更小,适合网络传输或嵌入式系统。
- 在代码中需通过
InputStream
或字节数组处理(如 Java 的Files.readAllBytes()
)。
-
SSH 公钥的独特性
- 格式固定为
[算法] [Base64密钥] [注释]
,注释常用于标识密钥用途(如邮箱)。 - 非标准 PEM/DER,需专用库解析(如 Java 的
JSch
或Apache Mina SSHD
)。
- 格式固定为
-
代码中的转换
- PEM → Base64:
String pem = Files.readString(Paths.get("public.pem")); String base64 = pem.replace("-----BEGIN PUBLIC KEY-----", "") .replace("-----END PUBLIC KEY-----", "") .replaceAll("\\s", ""); // 去空格和换行
- DER → Base64:
byte[] derBytes = Files.readAllBytes(Paths.get("public.der")); String base64 = Base64.getEncoder().encodeToString(derBytes);
- PEM → Base64:
开发建议
- 优先使用 PEM:文本格式易读、易存储,且兼容多数加密库(如 OpenSSL、Bouncy Castle)。
- 避免手动拼接:用标准工具生成密钥(如
OpenSSL
),避免格式错误:# 生成 PEM 公钥 openssl rsa -in private.pem -pubout -out public.pem
- 安全规范:
- 公钥可公开传递,但需验证来源(防止中间人篡改)。
- 私钥必须加密存储(如 PKCS#8 的
ENCRYPTED PRIVATE KEY
)。
通过统一密钥在不同格式间的转换,开发者可根据场景灵活选择:配置文件中用 PEM,网络传输用 Base64,嵌入式系统用 DER,SSH/Git 用专用格式。