RSA-PEM文件
一、格式
PEM(Privacy Enhanced Mail)是一种用于存储和传输加密对象的文件格式。
外观特征
1 | -----BEGIN <LABEL>----- |
常见类型
-----BEGIN PUBLIC KEY-----:公钥
包含:n、e
-----BEGIN RSA PUBLIC KEY-----:RSA 公钥(较老格式,较少见)
包含:n、e
-----BEGIN PRIVATE KEY-----:PKCS#8 通用 私钥-----BEGIN (RSA) PRIVATE KEY-----:PKCS#1 RSA 私钥-----BEGIN CERTIFICATE-----:X.509 证书(其中包含公钥
生成公私钥:
1 | from Crypto.PublicKey import RSA |
在python中利用公私钥文件,通过PKCS1_OAEP算法填充实现加解密
1 | from Crypto.PublicKey import RSA |
二、OpenSSL
公钥文件
由私钥生成公钥:
1 | openssl rsa -in private.pem -pubout -out public.pem |
解析公钥文件:
1 | openssl rsa -pubin -in public.pem -text -noout |
只提取n:
1 | openssl rsa -pubin -in public.pem -modulus -noout |
转换为十进制:
1 | print(int('ABCD',16)) |
私钥文件
生成传统的 PKCS#1 RSA 私钥文件:
1 | openssl genrsa -out private.pem 2048 |
生成 PKCS#8 通用 私钥文件:
1 | openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048 |
解析私钥文件:
1 | openssl rsa -in private.pem -text -noout |
- modulus (n)
- publicExponent (e)
- privateExponent (d)
- prime1 (p)
- prime2 (q)
- exponent1 (d mod (p-1))
- exponent2 (d mod (q-1))
- coefficient (q^{-1} mod p)
给私钥文件加密:
1 | openssl rsa -aes256 -in private.pem -out encrypted_private.pem |
执行后提示输入两次密码,生成的 encrypted_private.pem 文件头部会多出Proc-Type: 4,ENCRYPTED 和加密参数
证书
1 | openssl x509 -in cert.pem -text -noout |
内容:
- 版本号、序列号
- 签名算法
- 颁发者 (Issuer)
- 有效期 (Validity)
- 主体 (Subject) —— 这就是证书持有者
- 公钥信息 (Subject Public Key Info) ——RSA中的n和e
提取公钥:
1 | openssl x509 -in cert.pem -pubkey -noout > public.pem |
格式转换
1 | openssl pkcs8 -topk8 -inform PEM -in private_pkcs1.pem -outform PEM -out private_pkcs8.pem -nocrypt |
加密与解密
1 | openssl pkeyutl -encrypt -pubin -inkey public.pem -in plain.txt -out cipher.bin |
签名与验证
1 | openssl dgst -sha256 -sign private.pem -out signature.bin data.txt |
常见问题
“Can’t open file”:检查路径,避免中文或空格,可用双引号包裹。
“RSA operation error”:可能填充方式不匹配,或私钥/公钥不对应,或密文损坏。
“Expecting: RSA PRIVATE KEY”:私钥格式不兼容,可使用
openssl rsa -in key.pem -check查看,必要时转换格式
三、损坏的pem文件
标记错误
当报错时:
1 | unable to load Public Key |
判断正确格式:
1 | openssl asn1parse -inform PEM -in public.pem |
观察 ASN.1 结构:
- PKCS#1 公钥:一个 SEQUENCE,包含两个 INTEGER(n, e)。
- PKCS#8 公钥:SEQUENCE 包含算法 OID 和 BIT STRING,BIT STRING 内部是 PKCS#1 公钥。
- PKCS#1 私钥:包含 version, n, e, d, p, q 等。
- PKCS#8 私钥:包含 version, algorithm, 私钥数据(OCTET STRING 内嵌 PKCS#1 私钥)。
如果报错,可以先去掉头尾,只保留 Base64 部分,然后用 openssl asn1parse -inform DER -in data.bin 查看
Base64编码错误
包含多余空格、不规则换行、非法字符
1 | # 去除所有空白字符(包括换行、空格、制表符),但保留字母数字+/= |
私钥加密
文件头有Proc-Type: 4,ENCRYPTED 和 DEK-Info: AES-256-CBC,<IV>
如果密码比较弱(简单单子数字),字典爆破:
1 | openssl rsa -in encrypted.pem -passin pass:password -out decrypted.pem |
部分参数泄露
手动提取
常见ASN.1类型标签
| 十六进制 | 类型 | 含义 |
|---|---|---|
| 02 | INTEGER | 整数 |
| 03 | BIT SRING | 位串(公钥嵌套公钥) |
| 04 | OCTET STRING | 字节串(私钥中包裹私钥数据) |
| 30 | SEQUENCE | 序列(容器,组合多个字段) |
| 31 | SET | 集合 |
INTEGER字段:标签+长度+值
- 标签:02
- 长度:
- 短格式:长度小于128:用一个字节表示,该字节最高位为0
- 长格式:长度大于等于128:第一个字节的最高位设为1,低7位表示后续用于表示长度的字节数,后接长度值(大端序)
eg.02 81 81:129 02 82 0100:256
值
四、例题
未完待续
参考
https://www.cnblogs.com/JustGo12/p/17725443.html
感谢
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Lamb!