一、RSA加密算法的原理
先上公式:
加密过程:其实就是明文的E次方对N取模
公钥:(E,N)
解密过程:密文的D次方对N取模
私钥:(D,N)
那么以上公式中的E、D、N分别代表什么,又是如何保证RSA加密算法的安全性的呢?
二、RSA加密为什么是安全的
一、原则:目前计算机无法将一个大整数分解成两个互质的数相乘的结果。如果我告诉你上面公式公式中的N就是这个大整数,而公钥和私钥中的E、D又是根据N计算得到的,那是不是想要破解的人 无法得到N,那么也就无法计算得到D、E,从而无法破解得到公钥和私钥了呢。
二、计算公式
三、举例
为了计算方便,p q 的值取小一旦,假设:p = 17,q = 19,
则:
(1)求N:N = p * q = 323;
(2)求L:L = lcm(p-1, q-1)= lcm(16,18) = 144,144为16和18对最小公倍数;
(3)求E:1 < E < L ,gcd(E,L)=1,即1 < E < 144,gcd(E,144) = 1,E和144互为质数,E = 5显然满足上述2个条件,故E = 5,此时公钥= (E,N)=(5,323);
(4)求D:求D也必须满足2个条件:1 < D < L,E*D mod L = 1,即1 < D < 144,5 * D mod 144 = 1,显然当D= 29 时满足上述两个条件。1 < 29 < 144,
5 *29 mod 144 = 145 mod 144 = 1,此时私钥=(D,N)=(29,323);
(5)加密:准备的明文必须是小于N的数,因为加密或者解密都要 mod N,其结果必须小于N。
假设明文 = 123,则 密文=(123的5次方)mod 323=225
(6)解密:明文=(225的29次方)mod 323 =123,所以解密后的明文为123。
RSA加密算法使用中需要注意的问题
一、加密算法中使用的Cipher不是线程安全的
二、加密的系统和解密的系统分开部署
三、密钥长度越大,生成密文的长度也就越大,加密的速度也就越慢,而密文也就越难被破解掉
四、RSA 加密实现不允许明文长度超过密钥长度减去 11(单位是字节,也就是 byte)。
如果我们定义的密钥(我们可以通过 java.security.KeyPairGenerator.initialize(int keysize) 来定义密钥长度)长度为 1024(单位是位,也就是 bit),生成的密钥长度就是 1024位 / 8位/字节 = 128字节,那么我们需要加密的明文长度不能超过 128字节 -11 字节 = 117字节
五、Java 默认的 RSA 实现 “RSA/None/PKCS1Padding” 要求最小密钥长度为 512 位(否则会报 java.security.InvalidParameterException: RSA keys must be at least 512 bits long 异常),也就是说生成的密钥、密文长度最小为 64 个字节。如果你还嫌大,可以通过调整算法提供者来减小密文长度:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
keyGen.initialize(128);
如此这般得到的密文长度为 128 位(16 个字节)。但是这么干密钥长度太短,容易被破解。