RSA簽名的PSS模式

本文由雲+社區發表javascript

做者:mariolujava

1、什麼是PSS模式?

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.二、填充的必要性

RSA算法比較慢,通常用於非對稱加密的private key簽名和public key驗證。因RSA算法沒有加入亂數,當出現重複性的原始資料,攻擊者會經過相同加密密文而猜想出原文,所以導入padding的機制來加強安全性。安全

TLS流程中的密鑰材料若不進行填充而直接加密,那麼顯然相同的key,會獲得相同的密文。這種在語義上來講,是不安全的。如下例子說明了無填充模式的安全漏洞。bash

  • m:明文
  • e,n:RSA參數(公鑰)
  • d:RSA參數(私鑰)
  • c:網絡傳輸密文

加密方加密m:c = m^e mod n,傳輸c網絡

解密方解密c:m = c^d mod n,還原mdom

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

因爲c在網絡上傳輸,若是網絡上有人對其進行c' = c*k^e mod n,這樣的替換函數

那麼解密方將獲得的結果是工具

(c*k^e)^d mod n測試

= (c^d mod n)* (k^ed mod n)

= m*k

即中間人有辦法控制m。

1.三、PSS的基本要素

使用PSS模式的RSA簽名流程以下:

img
圖一、RSA-PSS的填充模式

相比較PKCS#1 v1.5的padding簡單許多:

img
圖二、RSA-PKCS#v1.5的填充模式

PSS的一些概念:

  • hash算法,通常使用SHA-1
  • MGF函數(mask generation function)。默認是MGF1。
  • salt length,通常由hLen決定。當爲0時,簽名值變成了惟一肯定的。
  • 截斷符號,通常是0xbc

2、RSA簽名實際操做

這節例子中所涉及到的文件說明:

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

/tmp/pub: 公鑰

/tmp/data: 明文

/tmp/endata: 密文

/tmp/sign: 簽名

/tmp/de_sign: 解簽名

2.一、前期準備:公鑰和私鑰

  • 經過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.二、加密和解密(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.三、簽名和驗證(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.四、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
複製代碼

3、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階段)

此文已由騰訊雲+社區在各渠道發佈

獲取更多新鮮技術乾貨,能夠關注咱們騰訊雲技術社區-雲加社區官方號及知乎機構號

相關文章
相關標籤/搜索