专栏文章 RSA 签名的 PSS 模式

匿名 · 2019年02月14日 · 2084 次阅读

本文由云 + 社区发表

作者:mariolu

一、什么是 PSS 模式?

1.1、两种签名方式之一 RSA-PSS

PSS (Probabilistic Signature Scheme) 私钥签名流程的一种填充模式。目前主流的 RSA 签名包括 RSA-PSS 和 RSA-PKCS#1 v1.5。相对应 PKCS(Public Key Cryptography Standards)是一种能够自我从签名,而 PSS 无法从签名中恢恢复原来的签名。openssl-1.1.x 以后默认使用更安全的 PSS 的 RSA 签名模式。

1.2、填充的必要性

RSA 算法比较慢,一般用于非对称加密的 private key 签名和 public key 验证。因 RSA 算法沒有加入乱数,当出现重复性的原始资料,攻击者会通过相同加密密文而猜测出原文,因此导入 padding 的机制來加強安全性。

TLS 流程中的密钥材料若不进行填充而直接加密,那么显然相同的 key,会得到相同的密文。这种在语义上来说,是不安全的。以下例子说明了无填充模式的安全漏洞。

  • m:明文
  • e,n:RSA 参数(公钥)
  • d:RSA 参数(私钥)
  • c:网络传输密文

加密方加密 m:c = me mod n,传输 c

解密方解密 c:m = cd mod n,还原 m

  • c':篡改密文
  • k:篡改码

由于 c 在网络上传输,如果网络上有人对其进行 c' = c*ke mod n,这样的替换

那么解密方将得到的结果是

(c*ke)d mod n

=(cd mod n)*(ked mod n)

= m*k

即中间人有办法控制 m。

1.3、PSS 的基本要素

使用 PSS 模式的 RSA 签名流程如下:

img图 1、RSA-PSS 的填充模式

相比较 PKCS#1 v1.5 的 padding 简单许多:

img图 2、RSA-PKCS#v1.5 的填充模式

PSS 的一些概念:

  • hash 算法,一般使用 SHA-1
  • MGF 函数(mask generation function)。默认是 MGF1。
  • salt length,一般由 hLen 决定。当为 0 时,签名值变成了唯一确定的。
  • 截断符号,一般是 0xbc

二、RSA 签名实际操作

这节例子中所涉及到的文件说明:

/tmp/wildcard_domain.sports.qq.com.v2.key:私钥

/tmp/pub: 公钥

/tmp/data: 明文

/tmp/endata: 密文

/tmp/sign: 签名

/tmp/de_sign: 解签名

2.1、前期准备:公钥和私钥

  • 通过 key 文件提取出 public key
openssl rsa -in /usr/local/services/ssl_agent/ca/wildcard_domain.sports.qq.com.v2.key -pubout -out /tmp/pub
  • 原始数据:

echo -n "1234567890" > /tmp/data

  • 这样就有一对公钥和私钥,用来测试 RSA 加密解密(encrypt、decrypt)和签名验证(sign,verify)
  • RSA 加密的两种算法分别是 RSAES-PKCS-v1_5 and RSAES-OAEP。

2.2、加密和解密(encrypt,decrypt)

  • 加密:
openssl rsautl -pubin -inkey /tmp/data -in /tmp/data -encrypt -out /tmp/endata
  • 解密,用 private key 解密,得到原本的值:
openssl rsautl -inkey /tmp/wildcard_domain.sports.qq.com.v2.key -in /tmp/en_data -decrypt

2.3、签名和验证(sign, verify)

签名过程包括 hash 和加密。hash 函数一般使用 sha1。这样输入明文,直接生成 sign 签名。

如果是私钥签名所做的事就是先 hash 再加密,选择一种 hash 算法把原始消息计算后成 ASN1 格式,再把这个资料用 private key 加密后送出,资料本身不加密,这种方式主要是用來验证资料来源是否可信任的,送出時把原始资料和签名一起送出。

  • 签名:
openssl sha1 -sign /tmp/wildcard_domain.sports.qq.com.v2.key  /tmp/data > /tmp/data/sign/tmp/data/sign
  • 解开签名:
openssl rsautl -pubin -inkey /tmp/pub -in sign -verify -out /tmp/de_sign 

用 public key 解开签名,并且保留 padding

openssl rsautl -pubin -inkey /tmp/pub -in /tmp/sign -encrypt -raw -hexdump

使用解开 ASN1 解开签名,或者签名后用 ASN1 工具解析

openssl rsautl -pubin -inkey /tmp/pub -in /tmp/sign -verify -asn1parse

或者:

openssl asn1parse -inform der -in /tmp/de_sign

和本地 sha1 对比

openssl sha1 /tmp/data

如果两者 hash 结果是一样,那么确定签名送过来是正确的。

2.4、openssl rsautl 工具支持的填充模式

openssl rsautl --help,可以看到支持的 padding 模式有,在 rsautl 加上以下选项可以重复做 2.2~2.3 的实验。

-ssl                     Use SSL v2 padding
-raw                     Use no padding
-pkcs                    Use PKCS#1 v1.5 padding (default)
-oaep                    Use PKCS#1 OAEP

三、PSS 填充模式的特点

PSS 是 RSA 的填充模式中的一种。

完整的 RSA 的填充模式包括:

RSA_SSLV23_PADDING(SSLv23填充)
RSA_NO_PADDING(不填充)
RSA_PKCS1_OAEP_PADDING (RSAES-OAEP填充,强制使用SHA1,加密使用)
RSA_X931_PADDING(X9.31填充,签名使用)
RSA_PKCS1_PSS_PADDING(RSASSA-PSS填充,签名使用)
RSA_PKCS1_PADDING(RSAES-PKCS1-v1_5/RSASSA-PKCS1-v1_5填充,签名可使用)

其中主流的填充模式是 PKCS1 和 PSS 模式。

PSS 的优缺点如下:

  • PKCS#1 v1.5 比较简易实现,但是缺少 security proof。
  • PSS 更安全,所以新版的 openssl-1.1.x 优先使用 PSS 进行私钥签名(具体在 ssl 握手的 server key exchange 阶段)

此文已由腾讯云 + 社区在各渠道发布

获取更多新鲜技术干货,可以关注我们腾讯云技术社区 - 云加社区官方号及知乎机构号

共收到 2 条回复 时间 点赞

楼主,麻烦加下我微信,lihuazhang2013,我们来聊聊你发帖子做宣传的频率。

匿名 #1 · 2019年02月15日
恒温 回复

您好,我搜不到您的微信,我的微信号:369888071

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册