前言
⭐️在阅读本文前,请注意,本文中出现的词汇:证书=公钥,密钥用于指代一对公钥和私钥。
⭐️在加解密和加验签中,私钥仅己方保存一份,公钥颁发出去可能给多个人保存。
⭐️一般证书(公钥)用于加密,私钥用于加签,因为签名需要不可伪造,具有唯一性。
⭐️本文按照个人习惯,整理了下常见的公私钥格式
有任何问题欢迎提出,便于及时修正
1、公私钥的文件编码格式
?核心数据类似于UTF-8、GBK的关系,只不过pem格式会在der外多加一层约定的文字。
?常见的公私钥后缀:.pem .der .cer .crt .pfx .p12 .jks。
?证书后缀与文件编码内容不一定一致
1.1 DER格式
- 内容格式:二进制表示数据
- 存储类型:仅限证书
- 文件后缀:der、cer、crt这几种通常都是DER
- 内容例子:打开都是二进制乱码,或者因为是二进制而无法正常打开
1.2 PEM格式
-
内容格式:把二进制内容转换成ASCII码。含标准开头与结尾,中间为base64后的文字。
-
存储类型:证书或私钥
-
文件后缀: pem
-
内容例子:
PEM实际上就是把DER编码的文件的二进制内容用base64编码一下,然后加上
-----BEGIN label-----
和-----END label-----
这样的头尾,中间则是DER文件的Base64编码。例如:-----BEGIN label----- BASE64Encoded -----END label-----
2、公私钥的数据结构编码格式
使用的加密标准,例如X.509标准 和 PKCS(公钥加密标准)系列(PKCS#1、PKCS#8、PKCS#12)
xx格式证书/密钥一般指符合该标准格式的证书/密钥
2.1 X.509格式证书
- 名称:X.509是密码学里公钥证书的格式标准
- 仅含证书。X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。
2.1 PKCS#1格式
-
名称:RSA Cryptography Standard,RSA密码学标准。
-
可以含公钥,也可以含私钥。没有版本或算法标识符。介绍了RSA算法的计算过程,包括:key的产生,key的结构(RSA Public Key和Private Key数学属性和格式),对数字加密/解密/签名/验证签名的过程、对应算法。
-
用途:主要针对RSA算法的加解密、加验签。
-
拓展:PKCS1填充模式
公钥例子
一个PKCS#1公钥,以以下标签开头和结尾:
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
在base64编码数据中,存在以下ASN.1语法结构(RFC8017 A.1.1):
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
注:RFC8017废弃了RFC3447
私钥例子
一个PKCS#1的私钥,以以下标签开头和结尾:
-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
在base64编码数据中,存在以下ASN.1语法结构(RFC8017 A.1.2):
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
2.2 PKCS#8格式
- 名称:Private-Key Information Syntax Specification,私钥信息格式规范。
- 可以含公钥,也可以含私钥
公钥例子
-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----
在 base64 编码数据中,存在以下结构,ASN.1语法描述为:
PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
未加密的私钥例子
未加密的 PKCS#8 编码数据格式如下:
-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----
在 base64 编码数据中,存在以下结构,ASN.1语法描述为:
PrivateKeyInfo ::= SEQUENCE {
version Version,
algorithm AlgorithmIdentifier,
PrivateKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
加密的私钥例子
加密的PKCS#8 编码数据格式如下:
-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64Encoded
-----END ENCRYPTED PRIVATE KEY-----
在 base64 编码数据中,存在以下结构,ASN.1语法描述为:
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier,
encryptedData EncryptedData
}
EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
EncryptedData ::= OCTET STRING
2.3 PKCS#12格式
- 名称:个人消息交换与打包语法
- 定义了通常用来存储Private Keys和Public Key Certificates(例如前面提到的X.509)的文件格式,使用基于密码的对称密钥进行保护。PKCS #12文件实际上是一个Keystore,PKCS #12文件可以被用做Java Key Store(JKS)。
- 文件后缀:一般为 .p12 或 .pfx
3、拓展
3.1 ASN.1
ASN.1是一种用来定义数据结构的描述语言,有点类似于学习数据结构时用的伪代码。
引用和参考
https://chanjarster.github.io/post/x509-pkcs-file-formats/
https://blog.ndpar.com/2017/04/17/p1-p8/
https://www.jianshu.com/p/a428e183e72e
https://www.jianshu.com/p/bc32cbfe49e7
https://blog.csdn.net/itworld123/article/details/115553346