今天遇到加密字符串过长,导致前端加密后传到后台的密文被解密失败,然后就去研究了一下RSA加密,记录一下。
一、秘钥生成的过程:
1、随机选择两个不相等的质数p和q
2、计算p和q的乘积n,n即密钥长度
3、计算n的欧拉函数φ(n)
4、随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质
5、计算e对于φ(n)的模反元素d
6、将n和e封装成公钥,n和d封装成私钥
加密(c为密文,m为明文): me ≡ c (mod n)
解密(c为密文,m为明文): cd ≡ m (mod n)
注:≡(恒等于符号)
对极大整数做因数分解(由n,e推出d)的难度决定了RSA算法的可靠性。就是说,对一极大整数做因数分解愈困难,RSA算法愈可靠。
假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。
今天只有短的RSA密钥才可能被暴力破解。只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。
目前一般为1024 bit以上的密钥(我们目前用的也是1024bit)。
二、关于解密长度限制
RSA算法本身要求加密内容也就是明文长度m必须0
例如我们目前项目用的秘钥长度为1024bit,那么加密长度就不能超过1024。
如果m=0,普遍RSA加密器会直接返回全0结果。
如果m>n(加密信息>秘钥长度),由于me ≡ c (mod n),c为密文,m为明文,e和n组成公钥,显然当m>n时,m与m-n得出的密文一样,无法解密,运算就会出错。所以,RSA 1024实际可加密的明文长度最大也是1024bits。
如果m
说一下RSA加密的padding填充方式有三种:
1、.RSA_PKCS1_PADDING (填充模式,最常用的模式)
要求:输入长度必须比RSA钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11,如果输入的明文过长,必须切割,然后填充
输出:和modulus一样长
比如:对于512bit的密钥,block length = 512/8 – 11 = 53 bytes
注:1bytes = 8bits
2、.RSA_PKCS1_OAEP_PADDING
输入:RSA_size(rsa) – 41
输出:和modulus一样长
3、for RSA_NO_PADDING 不填充
输入:可以和RSA钥模长一样长,如果输入的明文过长,必须切割,然后填充
输出:和modulus一样长
RSA算法在运算时需要将数据填充至分组长度(与RSA密钥模长相等)。
PAD方式分下面两种:
EM = 0x00 || 0x01 || PS || 0x00 || T
PS : pad with 0xFF, length : Len(EM) - 3 - Len(T)
EM = 0x00 || 0x02 || PS || 0x00 || M
PS : pad with random data, length : Len(EM) - 3 - Len(M)
填充串PS的长度最少为8个字节,这是RSA操作的一种安全措施。所以RSA签名的数据长度不能超过分组长度-11字节。
根据RSADSI颁布的RSA加密解密标准PKCS#1(为了避免RSA算法的一些漏洞),在加密的时候,会在data前面加入至少11bytes的padding
第一byte全置0
第二byte为格式位,全置2时为加密,全置1时为签名
接着是至少八byte的padding,random nonzero。
最后一byte全置0
因此padding总长至少为11byte。
这样,128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。
所以我们在把明文进行RSA加密前,要确认这个值是不是大于n。