Openssl提供了强大证书功能,生成密钥对、证书,颁发证书、生成crl、验证证书、销毁证书等。本文将j介绍如何利用openssl的命令分析RSA私钥文件格式,同时也将简单介绍几种常见的私钥文件格式。
1 生成私钥文件
openssl有多种方法生成私钥:
这里我使用genpkey命令生成RSA私钥文件,选择DES-EDE3-CBC算法进行加密,口令是1234:
[plain] view plain
opensslgenpkey-algorithmRSA-outprivatekey.pem-passpass:1234-des-ede3-cbc
命令执行后输出私钥文件privatekey.pem,默认输出为PEM格式,密钥长度为1024,接下来使用文本工具直接打开该文件,可以看到如下内容:
[html] view plain
私钥经过PEM编码后在文件头尾都添加了标签,用以说明当前的文件格式。从标签内容也可以看出私钥是加密的,因为有“ENCRYPTED”。中间的私钥内容是经过BASE64编码的,这样方便私钥的传递,例如在网络上传输,数据复制粘贴。
例子只是PEM文件格式的其中一种,以下是平时可能会碰到的PEM私钥格式:
PKCS#8 私钥加密格式
[html] view plain
PKCS#8 私钥非加密格式
[html] view plain
Openssl ASN格式
[html] view plain
除了以上几种,还有微软的PVK格式;以及DER编码格式,就是在使用PEM编码前的数据,由于没有密码保护,平时很少直接使用。
Openssl ASN格式在加密私钥数据时只能用MD5算法生成key,而且只迭代计算了1次。
所以从1.0.0开始Openssl把PKCS#8格式作为默认格式,可以为私钥文件提供更好的安全性和扩展性。
我们这里就针对PKCS#8格式的私钥进行讨论。 如果大家想要研究其他格式,可以使用以下命令:
genrsa 生成ASN格式
rsa 生成或转换为PVK格式
[html] view plain
opensslrsa-inprivatekey.pem-outprivatekey.pvk-outformPVK
2 分析私钥文件
使用asn1parse命令读取私钥ASN.1结构,其中–i表示输出使用缩进格式。
openssl asn1parse -i -in privatekey.pem
[html] view plain
ASN.1结构输出格式说明:
[html] view plain
0 表示节点在整个文件中的偏移长度
d=0 表示节点深度
hl=4表示节点头字节长度
l=710表示节点数据字节长度
cons 表示该节点为结构节点,表示包含子节点或者子结构数据
prim 表示该节点为原始节点,包含数据
SEQUENCE、OCTETSTRING等都是ASN.1中定义的数据类型,具体可以参考ASN.1格式说明。
最后一个节点OCTET STRING [HEX DUMP],就是加密后的私钥数据。
为了方便理解,下面给出相关的PKCS定义。
PCKS#8文件格式定义:
[html] view plain
privateKey,加密后私钥数据,最后一个OCTET STRING数据块。
privateKeyAlgorithm,使用的私钥算法,,详细格式在PKCS#52.0中的定义:
[html] view plain
keyDerivationFunc
加密密钥生成函数,现在默认使用的是sha1,还包含了salt,迭代次数iterationCount:
[html] view plain
[html] view plain
encryptionScheme
加密算法,例子中使用的是des-ede3-cbc,该结构中还包含初始化向量iv。
[html] view plain
解密流程:
1 按PKCS#8和PCKS#5定义从文件中解析出相关参数:
加密密钥生成函数(KDF)PBKDF2;
加密时使用的salt:7A61B055165A89CA,以及迭代次数iter:0x0800(2048次);
加密算法des-ede3-cbc,以及加密初始向量iv:110E8A184EFEAB9C
2 解析出加密的私钥数据data,也就是最后一个OCTET STRING;
3 生成加密密钥:key = KDF(pass(1234),salt,iter)
4 解密 des-ede3-cbc(key, iv, data)
这一解密过程可以使用openssl的pkey命令完成,执行完成后得到privatekey.der文件,这个是没有加密的私钥文件,数据是ASN.1格式,并使用DER编码。
Openssl pkey -in privatekey.pem -out privatekey.der-passin pass:1234
然后再次分析密钥数据,由于输入是der格式,需要使用inform参数说明:
openssl asn1parse -in privatekey.der -inform DER
[html] view plain
得到的数据与上次导出的格式是相同的,虽然看起来数据多,但是层次结构起始要简单,数据就是一个结构体(cons)SEQUENCE,包含9个整型的原始数据(prim)INTERGER,这个就是私钥结构,该 ASN.1结构在PKCS#1中定义如下:
[html] view plain
最后一个otherPrimeInfos是可选项,例子中没有该数据。
结构中包含了RSA密钥算法中用到的所有信息,每一项的具体定义可以参考PKCS#1。
3 分析公钥
为了方便获取公钥,在私钥文件数据中起始包含了公钥信息:
一遍一遍的……你突然明白自己还活着,