公开秘钥基础知识
# PKI
PKI 全称为 Public Key Infrastructure,直译为公开密钥基础设施,即利用公开密钥的机制建立起来的基础设施。第一代 PKI 标准主要包括:
X.509 国际电信联盟(ITU-T)制定的数字证书标准,规定了数字证书的格式。
PKCS
美国 RSA 数据安全公司及其合作伙伴制定的一组公钥密码学标准。PKCS 公布了很多标准,如
- PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制
- PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法。
# PKCS
到1999年底,PKCS(Public-Key Cryptography Standards)已经公布了以下标准:
PKCS#1:定义RSA公开密钥 (opens new window)算法加密和签名机制,主要用于组织PKCS#7 (opens new window)中所描述的数字签名 (opens new window)和[数字信封]https://baike.baidu.com/item/数字信封。
PKCS#3:定义Diffie-Hellman (opens new window)密钥 (opens new window)交换协议。
PKCS#5:描述一种利用从口令派生出来的安全密钥 (opens new window)加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式 (opens new window)加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息。
PKCS#6:描述了公钥证书 (opens new window)的标准语法,主要描述X.509证书 (opens new window)的扩展格式。
PKCS#7 (opens new window):定义一种通用的消息语法,包括数字签名 (opens new window)和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息。
PKCS#8:描述私有密钥信息格式,该信息包括公开密钥 (opens new window)算法的私有密钥以及可选的属性集等。
PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥 (opens new window)加密信息的属性类型。
PKCS#10:描述证书请求语法[29]。
PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡 (opens new window)之类的加密设备。
PKCS#12 (opens new window):描述个人信息交换语法标准。描述了将用户公钥 (opens new window)、私钥、证书和其他相关信息打包的语法。
PKCS#13:椭圆曲线密码体制 (opens new window)标准。
PKCS#14:伪随机数 (opens new window)生成标准。
PKCS#15:密码令牌信息格式标准。
# PKCS#8 和 PKCS#1区别
PKCS#1 ASN.1 RFC 2347 (opens new window)定义,里面包含了n、e、d值,其他参数都可以通过n、e、d计算得到,这里应该是为了方便用户使用,减少因用户计算方式不正确而导致一些操作的失败,故而直接把各种形式的参数定义在私钥里面。
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
}
2
3
4
5
6
7
8
9
10
11
PKCS#8的 ASN.1 RFC 5208 (opens new window)定义:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
privateKey PrivateKey,
attributes [0] Attributes OPTIONAL
}
2
3
4
5
6
PKCS#1形式的密钥专指RSA的密钥,如果一个ECC的密钥就无法用PKCS#1形式来表达。那么有没有一个通过的机构既可以表示RSA密钥,又可以表示ECC的密钥呢?有,这个就是PKCS#8形式的密钥。
从时间顺序上可以看出来,PKCS标准也是在不断发展的,PKCS1的标准是先于PKCS8出来的,那时候甚至非对称算法还只有RSA是成熟的,在计算机领域刚刚得到应用,PKCS专门将RSA的算法作为一个标准输出就不难理解了。随着加密算法的发展才有了PKCS8出来专门做存储密钥这样一件事情。
# X509
X.509是常见通用的证书格式。所有的证书都符合为Public Key Infrastructure (PKI) 制定的 ITU-T X509 国际标准。X.509是国际电信联盟-电信(ITU-T)部分标准和国际标准化组织(ISO)的证书格式标准。作为ITU-ISO目录服务系列标准的一部分,X.509是定义了公钥证书结构的基本标准。1988年首次发布,1993年和1996年两次修订。当前使用的版本是X.509 V3,它加入了扩展字段支持,这极大地增进了证书的灵活性。X.509 V3证书包括一组按预定义顺序排列的强制字段,还有可选扩展字段,即使在强制字段中,X.509证书也允许很大的灵活性,因为它为大多数字段提供了多种编码方案.
# 常见公开秘钥加密演算法
- RSA (opens new window)
- 椭圆曲线加密算法(Elliptic Curve Cryptography, ECC)
- SM2(国密)
- ElGamal (opens new window)
- 背包算法
- Rabin(RSA的特例)
- 迪菲-赫尔曼密钥交换协议中的公钥加密算法
使用最广泛的是RSA算法 (opens new window)(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开金钥加密算法,ElGamal是另一种常用的非对称加密算法 (opens new window)。
# 常见证书后缀
.pfx
常用于Windows上的 IIS服务器.p12
常用于MAC OS、iOS中(PKCS#12由PFX进化而来的用于交换公共的和私有的对象的标准格式).jks
Java Key Storage,这是Java的专利,JAVA的专属格式,一般用于 Tomcat 服务器。.cer/crt
编码方式不一定,可能是DER也可能是PEM.pem
都是PEM编码格式,文件中可以放证书或者私钥,或者两者都有,pem如果只含私钥的话,一般用.key
扩展名,而且可以有密码保护.der
都是DER编码格式,文件一般只放证书,不含私钥
.p7b
以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥.csr
- Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥key,私钥要自己保管好。做过iOS APP的朋友都应该知道是怎么向苹果申请开发者证书的吧.