引言
现有的大部分RSA算法实现都遵循PKCS#1 v2.1/v1.5 (2002/1993)。根据PKCS#1的建议,公钥指数e是可以选取较小的素数3或65537(=2^16+1)。这样选取主要是为了提高加密或签名验证的性能,因为3或65537分别只需要2或17次模乘运算,而一个随机选择的e(假设n是1024-bit)则大约需要1000次。这种选用小公钥指数的方法使用户相信RSA在签名验证和加密操作方面确实要比“以高效著称的ECC”还要高效很多。
然而在选用小公钥指数时,有很多人则更倾向于选e=65537而不是e=3,他们认为3“似乎不安全”,然而又给不出所以然。今天我想说的是,在“正确使用”RSA算法的情况下,至今为止还没有发现公开的攻击方法能有效攻击e=3。那么何为正确使用呢?很简单,如果你不是密码专家,那么实现时请遵守PKCS#1 v2.1或IEEE P1363的建议,而不要局限于自己对RSA的教科书式的理解。或者使用公开的密码算法库,如OpenSSL,这些算法的实现一般都会遵守相关标准或建议。
选择e=3究竟有什么问题?
对于e=3的情形,至今以来,其签名验证或加密的性能优势是任何公钥密码算法都无法超越的。但对其所存在的安全脆弱性,我们应实事求是地进行分析,而不要轻易放弃使用e=3。下面我来梳理一下自从1977年RSA算法诞生以来针对小公钥指数(e=3)的密码分析中值得一提的结论。
(1) Hastad攻击
Hastad描述的攻击经常也被称为广播攻击[1]。
攻击场景:如果Alice打算将消息M加密发送给一组用户,并且这组用户选择的公钥指数e=3,那么攻击者Malice可以通过截获3个密文
C1 = M^3 mod N1, C2 = M^3 mod N2, C3 = M^3 mod N3
便能够有效地恢复出明文M。Hastad进一步指出,即使Alice在加密M之前对M进行了f运算(这里f是一个公开的多项式函数),攻击者仍然能有效地恢复出明文M。所以建议在进行消息填充时一定要选择随机化填充方法,比如OAEP[2],而不是一个确定的填充方法。
影响:PKCS#1 v2.1和v1.5均不受此攻击的影响。
(2) Franklin-Reiter攻击
Franklin-Reiter攻击是一种明文相关性攻击[3]。
攻击场景:假设Bob的公钥为(3, N),Alice发送消息M1和M2给Bob,并且M1 = f(M2) mod N,f是一个已知的多项式。那么攻击者Malice可以截获密文
C1 = M1^3 mod N, C2 = M2^3 mod N
便能够有效地恢复出明文M。所以建议明文在加密前一定要做随机化处理。
影响:PKCS#1 v2.1和v1.5均不受此攻击的影响。
(3) Coppersmith攻击
首先我们介绍Coppersmith发现的短填充攻击[4]。
攻击场景:假设Bob的公钥为(3, N),Alice发送消息M给Bob。消息M的填充方法是遵循PKCS#1 v1.5,即在消息尾部或头部直接填充随机串。如果攻击者截获到Alice发送给Bob的关于消息M的两个不同的密文,即
C1 = (0002||r1||M)^3 mod N, C2 = (0002||r2||M)^3 mod N
如果填充的随机串r的长度低于消息长度的1/9,那么攻击者便能够有效地恢复出明文M。注意该攻击对e = 65537无效。
影响:PKCS#1 v2.1不受影响,但PKCS#1 v1.5受此攻击的影响。
[补充说明] Coppersmith在密码分析领域做了很多杰出的工作,比如Coppersmith定理[4]已经成为一个密码分析工作的奠基石。
Coppersmith定理:令N为大整数,f是度为e的多项式。给定N和f,可以有效地计算出方程f(x)=0 mod N所有小于N^(1/e)的解。
应用该定理,另一个简单的攻击如下:当e=3时,给定一个密文,如果攻击者已知2/3的明文比特,则能恢复出整个明文。
(4) BDF攻击
BDF攻击[5]是针对私钥d在部分暴露之后的攻击。
攻击结论:令(N, d)为私钥,N的长度为n-bit。假若d的n/4个低位比特信息被泄露,那么在e < sqrt(N)条件下,攻击者可以有效地恢复出私钥d。
另外值得一提的是,如果e = 3,我们很容易知道d的取值范围,而且这个取值范围的区间为sqrt(N)量级。这也就是说,如果e = 3,RSA就天然地泄露了d的一半比特位信息,只不过泄露的是高位比特,而不是低位比特。但是目前还没有发现针对d的高位比特泄露的有效攻击。
影响:PKCS#1 v2.1和v1.5均不受此攻击的影响。
(5) 其它攻击
关于RSA的其它相关攻击,如小私钥指数攻击、共模攻击、盲化攻击、时间攻击等,请参见[6, 7].
结论
(I) 对于RSA加密来说,如果在实现上遵循PKCS#1 v2.1 (OAEP填充),目前还没有发现有效的攻击;但如果是遵循PKCS#1 v1.5 (明文尾部直接填充),那么存在Coppersmith攻击。
(II) 对于RSA签名来说,目前对于PKCS#1 v2.1 (PSS填充)和PKCS#1 v1.5 (填充方法:0001FF...FF00||ASN.1||H(M))来说都还没有发现有效的攻击。
综上所述,选用e=3作为RSA的公钥指数,只要使用正确的填充方案,目前仍然是安全的。
关于e=65537的说明
这是一个推荐使用的公钥指数,我认为选这个值的目的只是一个介于低指数攻击和运算效率之间的一个折中考虑,即以防万一"e=3"被攻破而侥幸"e=65537"可能还是安全的。另外,NIST SP800-78 Rev 1 (2007) 也曾强调“不允许使用比65537更低的公钥指数e”,但对于该限制却没有给出任何理由。而PKCS#1却从未有过类似的建议。
(5) 其它攻击
关于RSA的其它相关攻击,如小私钥指数攻击、共模攻击、盲化攻击、时间攻击等,请参见[6, 7].
结论
(I) 对于RSA加密来说,如果在实现上遵循PKCS#1 v2.1 (OAEP填充),目前还没有发现有效的攻击;但如果是遵循PKCS#1 v1.5 (明文尾部直接填充),那么存在Coppersmith攻击。
(II) 对于RSA签名来说,目前对于PKCS#1 v2.1 (PSS填充)和PKCS#1 v1.5 (填充方法:0001FF...FF00||ASN.1||H(M))来说都还没有发现有效的攻击。
综上所述,选用e=3作为RSA的公钥指数,只要使用正确的填充方案,目前仍然是安全的。
关于e=65537的说明
这是一个推荐使用的公钥指数,我认为选这个值的目的只是一个介于低指数攻击和运算效率之间的一个折中考虑,即以防万一"e=3"被攻破而侥幸"e=65537"可能还是安全的。另外,NIST SP800-78 Rev 1 (2007) 也曾强调“不允许使用比65537更低的公钥指数e”,但对于该限制却没有给出任何理由。而PKCS#1却从未有过类似的建议。
参考文献:
[1] J. Hastad, Solving simultaneous modular equations of low degree. SIAM J. of Computing, 17: 336-341, 1988
[2] M. Bellare and P. Rogaway. Optimal asymmetric encryption. In EUROCRYPT'94, LNCS 950, pp 92-111, 1994.
[3] M. Franklin and M. Reiter, Low-exponent RSA with related messages. In EUROCRYPT'96, LNCS 1070, pp 1-9, 1996.
[4] D. Coppersmith. Small solutions to polynomial equations, and low exponent RSA vulnerabilities. Journal of Cryptology, 10: 233-260, 1997.
[5] D. Boneh, G. Durfee, and Y. Frankel. An attack on RSA given a fraction of the private key bits. In AsiaCrypt'98, LNCS 1514, pp 25-34, 1998
[6] D. Boneh, Twenty years of attacks on the RSA cryptosystem, 1999.
[7] http://www.rsa.com/rsalabs/node.asp?id=2216
[7] http://www.rsa.com/rsalabs/node.asp?id=2216
相关推荐
在Linux环境下,生成RSA公钥和PEM公钥文件通常涉及到加密和安全领域的知识,特别是公钥基础设施(Public Key Infrastructure, PKI)中的RSA算法。RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard ...
(去掉注释13.6kb)微信小程序RSA加密模块,用法请参考文件里面的注释。 //加载RSA模块 var RSA = require('rsa.js'); var rsa_res = new RSA.RSAKey(); //配置公钥证书 let public_n = ''; let public_e = ''; ...
在C#编程环境中,RSA(Rivest-Shamir-Adleman)是一种广泛使用的非对称加密算法,常用于确保数据的安全传输。私钥加密和公钥解密是RSA算法的核心特性,允许发送者使用接收者的公钥来加密数据,而只有持有对应私钥的...
linux下C语言从N(模数)、E(公钥指数)、D(私钥指数)得到了RSA结构体,可以进行RSA加密解密,也可以进行签名和验证签名(本代码没做这个,有RSA结构体这个很简单了)。完整源代码,可编译和测试。
有时候和其他系统对接的时候,对方发送的公钥指数、私钥指数和模数等参数,C#这边可以用这3个参数来实现加解密,即实现了从这三个参数得到密钥对,然后用密钥对去做加解密。如果只有公钥指数和模数,那么就可实现...
C#通过 n、e和d(模数、公钥指数和私钥指数)三个参数来RSA加解密及签名和验签。如果只是公钥解密和验证签名,那么可以不需要知道私钥指数(D),这在某些时候对方传过来N和E来解密和验签的时候非常管用(验证签名的...
总的来说,RSA算法在C# .NET中的实现涉及到了密钥对的生成、公钥加密、私钥解密等核心操作,理解这些概念对于开发安全的应用程序至关重要。在实际应用中,还需要考虑数据完整性校验、密钥管理等额外的安全措施。通过...
3. 找到e关于φ(n)的模反元素d,作为私钥的指数,即ed ≡ 1 mod φ(n)。 4. 公钥是(e, n),私钥是(d, n)。 加密时,发送方使用接收方的公钥(e, n)将明文转换为密文。加密公式为:C ≡ P^e mod n,其中P是明文,C是...
RSA算法是一种非对称加密技术,它在信息安全领域扮演着重要的角色。非对称加密与对称加密的主要区别在于,它使用两个不同的密钥:一个公钥用于加密,另一个私钥用于解密。RSA的名字来源于它的发明者Ron Rivest、Adi ...
RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因其发明者的名字首字母命名。这种加密算法基于大数因子分解的困难性,为数据的传输提供了强大的安全保护。在.NET环境下,我们...
在IT行业中,加密技术是确保数据安全的重要手段之一,RSA(Rivest-Shamir-Adleman)算法就是一种广泛使用的非对称加密算法。本文将深入探讨如何在ASP.NET环境中实现RSA加密,并且与PHP和Java进行互通,以及涉及的...
选取一个与φ(n)互质的整数e作为公钥的加密指数,再找到满足条件e*d mod φ(n) = 1的d作为私钥的解密指数。这样,e和d就构成了公钥和私钥对。 2. **公钥和私钥的生成**: 在本示例中,工具类提供了生成公钥和私钥...
RSA算法是一种非对称加密算法,它在信息安全领域有着广泛的应用,例如数字签名、数据加密等。在Java中实现RSA公钥和私钥的生成,通常我们会使用Java Cryptography Extension (JCE) 提供的API,如`java.security....
在IT领域,特别是软件开发中,安全通信是至关重要的,而RSA算法是广泛使用的非对称加密技术之一。本文将详细讲解Delphi环境下如何实现RSA加解密,并着重讨论其支持的公钥加密私钥解密以及私钥加密公钥解密的功能,...
RSA算法是一种非对称加密算法,它在信息安全领域有着广泛的应用,如数字签名、数据加密等。该算法基于两个大素数的乘积以及欧拉函数的性质,使得只有拥有特定密钥的人才能对信息进行解密。在这个C++实现中,我们将...
5. **选择加密指数e**:e是公钥的一部分,它必须满足1 < e φ(N)且e与φ(N)互质。通常,e取为65537,这是一个常用且方便的值,可以快速计算模幂。 6. **计算私钥d**:私钥d是公钥e的模逆元,即存在一个整数k使得d*e...
在.NET框架中,RSA是一种广泛使用的非对称加密算法,常用于实现数据的安全传输和存储。此源码项目“基于.net的RSA私钥加密 公钥解密的源码--201903”专注于利用C#语言来实现RSA算法的私钥加密和公钥解密功能。以下是...
这一特性使得RSA在信息传输中非常安全,因为即使有人截获了用公钥加密的信息,没有对应的私钥也无法解密。 公钥的生成过程如下: 1. 首先,随机选择两个大素数p和q,计算它们的乘积n=p*q。素数的选择是非常关键的,...
应用场景用于当你使用的是.net技术需要调用对方的接口时,但对方使用的是java语言时需要把对方提供的RSA私钥或者RSA公钥进行转换成.net格式进行使用。否则可能会出现解密失败的情况出现,相反就是你是java技术需要...
RSA公钥算法是一种广泛应用于网络安全中的非对称加密技术,由Ron Rivest、Adi Shamir和 Leonard Adleman 在1977年提出,因此得名RSA。它基于数论中的两个核心概念:大整数因子分解的困难性和欧几里得算法。在RSA中,...