PKCS1_SignatureScheme_PSS

8. Signature Scheme with Appendix

简称RSASSA

Two signature schemes with appendix are specified in this document:

  • RSASSA-PSS,适用于新应用,使用EMSA-PSS编码封装方案;
  • RSASSA-PKCS1-v1_5,处理旧应用兼容性,使用EMSA-PKCS1-v1_5编码封装方案。

To verify a signature constructed with this type of scheme, it is necessary to have the message itself.

签名和验签,其实就是加密和解密,不同的是两种签名的封装方案(Section 9)。

8.1. RSASSA-PSS

8.1.1. Signature Generation

RSASSA-PSS-SIGN (K, M)
    K signer’s RSA private key
    M message to be signed, an octet string
Output:
    S signature, an octet string of length k, where k is the length in octets of the RSA modulus n

一般明文M是一段hash。

Steps:

  1. EMSA-PSS encoding
EM = EMSA-PSS-ENCODE (M, modBits - 1);
# Note that the octet length of EM will be one less than k if  modBits - 1 is divisible by 8 and equal to k otherwise.
  1. RSA signature:
m = OS2IP (EM);
s = RSASP1 (K, m);
S = I2OSP (s, k);
  1. Output the signature S

8.1.2. Signature Verification Operation

 RSASSA-PSS-VERIFY ((n, e), M, S)
 Input:
     (n, e) signer’s RSA public key
     M message whose signature is to be verified, an octet string
     S signature to be verified, an octet string of length k, where k is the length in octets of the RSA modulus n
Output:
	"valid signature" or "invalid signature"

Steps:

  1. Length checking: S

  2. RSA verification:

s = OS2IP (S);
m = RSAVP1 ((n, e), s);
EM = I2OSP (m, emLen);
  1. EMSA-PSS verification
Result = EMSA-PSS-VERIFY (M, EM, modBits - 1);
# Note that emLen will be one less than k if modBits - 1 is divisible by 8 and equal to k otherwise.

9. Encoding Methods for Signatures with Appendix

9.1. EMSA-PSS

parameterized by

  • the choice of hash function
  • mask generation function
  • salt length
                      +-----------+
                      |     M     |
                      +-----------+
                            |
                            V
                           Hash
                            |
                            V
             +--------+----------+----------+
        M’ = |Padding1|   mHash  |   salt   |
             +--------+----------+----------+
                             |
     +--------+----------+   V
DB = |Padding2|   salt   |  Hash
     +--------+----------+   |
            |                |
            V                |
            xor <--- MGF <---|
            |                |
            |                |
            V                V
     +-------------------+----------+--+
EM = |      maskedDB     |    H     |bc|
     +-------------------+----------+--+

注意:DB的结构实际是 DB = PS || 0x01 || salt,原图中没有1。

参考源码:PyCryptodome, \Crypto\Signature\pss.py

9.1.1. Encoding Operation

EMSA-PSS-ENCODE (M, emBits)
Options:
     Hash hash function (hLen denotes the length in octets of the hash function output)
     MGF mask generation function
     sLen intended length in octets of the salt
Input:
     M message to be encoded, an octet string 
     emBits maximal bit length of the integer OS2IP (EM) (see Section 4.2), at least 8hLen + 8sLen + 9(no padding)
Output:
     EM encoded message, an octet string of length emLen = \ceil(emBits/8)

steps:

# 1. Length checking: M length for hashing
# 2
mHash = Hash(M)
# Step 3
if emLen < mhash.digest_size+sLen+2:
    raise ValueError("Digest or salt length are too long"
                     " for given key size.")
# Step 4 
#  if sLen = 0, then salt is the empty string
salt = randFunc(sLen)
# Step 5  string of length 8 + hLen + sLen
m_prime = bchr(0)*8 + mhash.digest() + salt
# Step 6
h = mhash.new()
h.update(m_prime)
# Step 7
ps = bchr(0)*(emLen - sLen - mhash.digest_size - 2)
# Step 8
db = ps + bchr(1) + salt
# Step 9
dbMask = mgf(h.digest(), emLen - mhash.digest_size - 1)
# Step 10
maskedDB = strxor(db, dbMask)
# Step 11 最左边的字节的左边8*emLen-emBits个位赋值为0
lmask = 0
for i in iter_range(8*emLen-emBits):
    lmask = lmask >> 1 | 0x80
maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:]
# Step 12
em = maskedDB + h.digest() + bchr(0xBC)

9.1.2. Verification Operation

EMSA-PSS-VERIFY (M, EM, emBits)
Input:
    M message to be verified, an octet string
    EM encoded message, an octet string of length emLen = \ceil(emBits/8)
    emBits maximal bit length of the integer OS2IP (EM) (see Section 4.2), at least 8hLen + 8sLen + 9
Output:
	"consistent" or "inconsistent"

steps:

# 1. Length checking: M length for hashing
# 2. 
mHash = Hash(M)
# Step 3
if emLen < mhash.digest_size+sLen+2:
    raise ValueError("Incorrect signature")
# Step 4
if ord(em[-1:]) != 0xBC:
    raise ValueError("Incorrect signature")
# Step 5
maskedDB = em[:emLen-mhash.digest_size-1]
h = em[emLen-mhash.digest_size-1:-1]
# Step 6
if lmask & bord(em[0]):
    raise ValueError("Incorrect signature")
# Step 7
dbMask = mgf(h, emLen-mhash.digest_size-1)
# Step 8
db = strxor(maskedDB, dbMask)
# Step 9
db = bchr(bord(db[0]) & ~lmask) + db[1:]
# Step 10
if not db.startswith(bchr(0)*(emLen-mhash.digest_size-sLen-2) + bchr(1)):
    raise ValueError("Incorrect signature")
# Step 11
if sLen > 0:
    salt = db[-sLen:]
else:
    salt = b""
# Step 12
m_prime = bchr(0)*8 + mhash.digest() + salt
# Step 13
hobj = mhash.new()
hobj.update(m_prime)
hp = hobj.digest()
# Step 14
if h != hp:
    raise ValueError("Incorrect signature")

实现

https://github.com/C0deStarr/CryptoImp/tree/main/pubkey/rsa

  • pkcs1_pss.h
  • pkcs1_pss.c

参考资料

RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值