RSA 数字签名算法(RSASA)的本质,仍然是 RSA 加密/解密算法,如图所示

java rsa 计算签名 rsa签名算法例题_随机数

RSSSA 分为两步。

1)将待签名的 M 进行 Hash,从而得到 H

2)将 H 进行 RSA 私钥加密

就绕不开 RSA 那个致命问题——能够非常简单地被选择密文攻击所破解,于是也就引发了 RSA 填充算法

RSASSA-PKCS1-v1_5 采用的就是 RSA_PKCS1_PADDING_v1_5 填充算法,而 RSASSA-PSS 的填充算法则与 RSA_PKCS1_OAEP_PADDING 填充算法比较相像。下面我们就介绍 RSASSA-PSS 算法。

一、RSASSA-PSS 的填充算法

RSASSA-PSS 算法本质就是在 RSA 算法的基础上叠加上一种填充算法(为了便于表述,这种填充算法也可以称为 RSA-PSS 填充算法,或者 RSA-PSS 编码),如图所示。

java rsa 计算签名 rsa签名算法例题_密码学_02


在 Hash 之后,在 RSA 之前,RSASA-PSS 算法插入了一个 RSA-PSS 填充算法。RSA-PSS 的具体算法 如图所示:

java rsa 计算签名 rsa签名算法例题_java rsa 计算签名_03


消息编码:在对消息M生成RSA-PSS签名的第一阶段处理过程是由M生成固定长度的消息摘要,成为消息编码(EM)。先定义如下的参数和函数:

选项 Hash 输出长度是hLen字节的Hash函数。目前的选择是SHA-1,该算法产生20字节的Hash值

MGF 掩码产生函数。目前规范中使用的是MGF1

sLen salt的字节长度。一般sLen=hLen,当前版本为20字节

输入 M 用于签名的待编码消息

emBits 该数是比RSA模数n位长度小的值

输出 EM 编码后的消息,是用于加密后形成消息签名的消息摘要

参数 emLen

填充1(padding1) 十六进制串 00 00 00 00 00 00 00 00;即64位的0

填充2(padding2) 十六进制串若干个00后面跟着01;其长度为(emLen-sLen-hLen-2)字节

salt(salt) 一组伪随机数

bc BC的十六进制值

二、 掩码产生函数

MGF通常基于安全Hash函数来构造,如SHA-1。基于密码学Hash函数的MGF用于产生任意长度消息的摘要或者hash值,输出固定长度的值。

目前RSA-PSS规范中使用的MGF函数是MGF1,其参数如下:

选项 Hash 输出长度是hLen字节的hash函数

输入 X 被掩码的字节串

maskLen 掩码的字节长度

输出 mask 长度为maskLen字节的串

MGF1的定义如下:

1)初始化变量

T=空字符串

java rsa 计算签名 rsa签名算法例题_java rsa 计算签名_04


2)计算中间值

for counter = 0 to k

将counter表示为32位串c的形式

T=T || Hash (X||C)

3)输出结果

mask = T 的前maskLen字节

本质上,MGF1的操作过程如下:如果需要的输出长度等于Hash值的长度(maskLen=hLen),则将输入值X的hash值链接取值为0的32位计数器,作为输出。maskLen比hLen大,MGF1继续讲当前处理的串T 与计数器连接并对X计算Hash,因此输出如下:

java rsa 计算签名 rsa签名算法例题_密码学_05


该过程直到T的长度大于或等于maskLen时结束,这时将T的前maskLen字节作为输出。

三、形成签名

java rsa 计算签名 rsa签名算法例题_随机数_06


下面介绍拥有私钥{d,n}和公钥{e,n}的签名者如何形成签名。字节串EM作为无符号的非负二进制整数s。通过如右方式加密m得到签名s:

java rsa 计算签名 rsa签名算法例题_密码学_07

令k是RSA模数n的字节长度。如RSA的密钥长度是2048位,则k=2048/8=256.然后将计算出的签名值s转换成k字节的串S

四、签名验证

解密:对于签名的验证,讲签名s作为无符号的非负二进制整数s。消息摘要m通过解密s得到:

java rsa 计算签名 rsa签名算法例题_密码学_08

然后将消息转换为编码后的消息EM的形式,其长度为

java rsa 计算签名 rsa签名算法例题_安全_09

字节,这里modBits是RSA模数n的位长度

java rsa 计算签名 rsa签名算法例题_java rsa 计算签名_10


java rsa 计算签名 rsa签名算法例题_密码学_11


上图过程,阴影部分的方块标记为H和H’,分别对应着解密后的签名中的值和直接从签名对应的消息中生成的值。剩下的三处阴影部分包括解密后的签名的值中与已知常数的比较部分。