PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准。
PKCS 目前共发布过 15 个标准:
(1)PKCS#1:RSA加密标准。PKCS#1定义了RSA公钥函数的基本格式标准,特别是数字签名。它定义了数字签名如何计算,包括待签名数据和签名本身的格式;它也定义了PSA公/私钥的语法。(2)PKCS#2:涉及了RSA的消息摘要加密,这已被并入PKCS#1中。
(3)PKCS#3:Diffie-Hellman密钥协议标准。PKCS#3描述了一种实现Diffie- Hellman密钥协议的方法。
(4)PKCS#4:最初是规定RSA密钥语法的,现已经被包含进PKCS#1中。
(5)PKCS#5:基于口令的加密标准。PKCS#5描述了使用由口令生成的密钥来加密8位位组串并产生一个加密的8位位组串的方法。PKCS#5可以用于加密私钥,以便于密钥的安全传输(这在PKCS#8中描述)。
(6)PKCS#6:扩展证书语法标准。PKCS#6定义了提供附加实体信息的X.509证书属性扩展的语法(当PKCS#6第一次发布时,X.509还不支持扩展。这些扩展因此被包括在X.509中)。
(7)PKCS#7:加密消息语法标准。PKCS#7为使用密码算法的数据规定了通用语法,比如数字签名和数字信封。PKCS#7提供了许多格式选项,包括未加密或签名的格式化消息、已封装(加密)消息、已签名消息和既经过签名又经过加密的消息。
(8)PKCS#8:私钥信息语法标准。PKCS#8定义了私钥信息语法和加密私钥语法,其中私钥加密使用了PKCS#5标准。
(9)PKCS#9:可选属性类型。PKCS#9定义了PKCS#6扩展证书、PKCS#7数字签名消息、PKCS#8私钥信息和PKCS#10证书签名请求中要用到的可选属性类型。已定义的证书属性包括E-mail地址、无格式姓名、内容类型、消息摘要、签名时间、签名副本(counter signature)、质询口令字和扩展证书属性。
(10)PKCS#10:证书请求语法标准。PKCS#10定义了证书请求的语法。证书请求包含了一个唯一识别名、公钥和可选的一组属性,它们一起被请求证书的实体签名(证书管理协议中的PKIX证书请求消息就是一个PKCS#10)。
(11)PKCS#11:密码令牌接口标准。PKCS#11或“Cryptoki”为拥有密码信息(如加密密钥和证书)和执行密码学函数的单用户设备定义了一个应用程序接口(API)。智能卡就是实现Cryptoki的典型设备。注意:Cryptoki定义了密码函数接口,但并未指明设备具体如何实现这些函数。而且Cryptoki只说明了密码接口,并未定义对设备来说可能有用的其他接口,如访问设备的文件系统接口。
(12)PKCS#12:个人信息交换语法标准。PKCS#12定义了个人身份信息(包括私钥、证书、各种秘密和扩展字段)的格式。PKCS#12有助于传输证书及对应的私钥,于是用户可以在不同设备间移动他们的个人身份信息。
(13)PDCS#13:椭圆曲线密码标准。PKCS#13标准当前正在完善之中。它包括椭圆曲线参数的生成和验证、密钥生成和验证、数字签名和公钥加密,还有密钥协定,以及参数、密钥和方案标识的ASN.1语法。
(14)PKCS#14:伪随机数产生标准。PKCS#14标准当前正在完善之中。为什么随机数生成也需要建立自己的标准呢?PKI中用到的许多基本的密码学函数,如密钥生成和Diffie-Hellman共享密钥协商,都需要使用随机数。然而,如果“随机数”不是随机的,而是取自一个可预测的取值集合,那么密码学函数就不再是绝对安全了,因为它的取值被限于一个缩小了的值域中。因此,安全伪随机数的生成对于PKI的安全极为关键。
(15)PKCS#15:密码令牌信息语法标准。PKCS#15通过定义令牌上存储的密码对象的通用格式来增进密码令牌的互操作性。在实现PKCS#15的设备上存储的数据对于使用该设备的所有应用程序来说都是一样的,尽管实际上在内部实现时可能所用的格式不同。PKCS#15的实现扮演了翻译家的角色,它在卡的内部格式与应用程序支持的数据格式间进行转换。
1. PKCS#1
-
PKCS#1签名就是按照PKCS#1标准中的编码标准,先将原文摘要按照一定标准进行封装和补位再做签名运算,如SHA1withRSA签名:RSA(Padding(DigestAlgorithmIdentifier+hash(msg)))这种格式称为PKCS1Padding,
-
NoPadding的签名则没有补位,直接对摘要值做签名运算:RSA(hash(msg))。
-
裸签名(RAWSign)
-
裸签名不严格的讲,包含PKCS1Padding签名和NoPadding格式的签名,严格的讲,应该专指NoPadding的签名。
-
RAW签名,属于PKCS#1标准的签名,验签时也可以支持验证NoPadding的签名。
-
-
签名
- 用SHA-1摘要算法对需要签名的数据(DATA)进行HASH运算,生成20字节HASH结果:H = SHA(DATA) H为20字节
- 按PKCS#1标准对HASH结果作填充;
- 使用发送方私钥(记作pvk)对填充后的数据块作RSA运算,生成128字节签名结果:SIGN = RSApvk(B) SIGN为128字节
-
验签:从接收签名结果记为SIGN,签名原数据为DATA,验签公钥为pbk,则验证签名的流程为:
- 使用公钥对签名结果作RSA公钥解密运算并去掉填充: H’ = RSApbk(SIGN)
- 对签名原数据作HASH运算:H = SHA(DATA)
- 比较H与H’,如相等,则验证正确,否则验证错误。
2. PKCS#7
- PKCS#7签名是在PKCS#1签名的基础上增加了签名者信息等内容后,并进行DER编码后的数据结构。
- 在数字签名结果中可以包含被签名数据(称为Attach方式)或不包含被签名数据(称为Detach方式);在数字签名结果中可以包含签名者证书也可以不包含签名者证书。“签名值”是通过私钥对“被签名内容”和其它可认证属性进行签名运算的结果。因此,在上述签名格式中的证书、CLRs、被签名内容等可以从已生成的签名结果中删除或重新插入。
一般情况下,签名格式根据下面的需要进行选择:
- 需要保存在数据库中的数字签名与被签名原数据采用分离的方式进行存放,即在“被签名内容信息”内不含实际的“被签名内容”,被签名内容存放在数据库其它地方。
- 不包含签名者证书,可以减少签名数据大小,但在验证时需要查找证书。
- 需要在网络上传输(例如与其它系统交换数据)的数字签名,在签名包中可以包含被签名数据和签名者证书。
数字签名前要对数据使用SHA-1或SM3数据摘要算法作HASH运算,再用 用户的签名私钥作RSA运算,结果即为对数据的“数字签名”。下面的DATA为待签名数据,HASH(…)为HASH函数,SIGN(…)为签名运算函数,DS为签名结果。
- 签名
- 对数据作HASH运算: H = SHA(DATA) H为20字节
- 按PKCS#1标准对HASH结果作填充;
- 使用用户的私钥(pvk)对填充后的数据块作RSA运算;DS = RSApvk(B) DS为128字节
- 按PKCS#7标准格式对签名进行编码,得到的结果记为signedData。
- 验签:设待验证的签名为signedData,签名原数据为DATA,则验证签名的流程为:
- 从signedData中提取签名者证书序列号等信息,按证书序列号获取签名者证书并检验证书的有效性(在签名中提取证书或通过LDAP下载证书);
- 从证书中提取签名者公钥(pbk),使用公钥对签名结果作RSA公钥解密运算并去掉填充: H’ = RSApbk(DS)
- 对签名原数据作HASH运算: H = SHA(DATA)
- 比较H与H’,如相等,则验证正确,否则验证错误。
- 数字信封:数字信封用于通信双方交换数据。发送方生成一个随机的报文密钥,使用报文密钥对发送内容进行加密(对称算法),再用接收方的公钥对报文密钥加密,最后将加密的报文密钥和加密的发送内容按PKCS#7标准,编码组成一个“数字信封”。发送方还可以为发送内容附加签名。