1 对RSA算法的理解RSA加密算法是一种非对称加密算法,它基于一个非常简单的数论思想:“将两个素数乘起来是很容易的,但是分解该乘积是非常困难的”。
1.1加解密步骤(1)生成公钥和私钥a)随机生成两个不相等的大素数p和q,计算N=p*q;b)根据欧拉函数,求出φ=(p-1)*(q-1);c)选择一个小于r的整数e,求e关于r的模反元素d使得e*d mod φ=1得到公钥<N,e>,私钥<N,d>(2)加密给定明文m,公钥<N,e>,计算密文c = m e(N)。
(3)解密给定密文c,私钥<N,d>,计算明文m’ = c d(N)。
1.2素性检验RSA算法的实现难点之一是生成大素数,这就需要生成一个大数并对其进行素性检验。
素性检验有很多种方法。
其中包括确定性方法和随机方法。
确定性方法有试除法(埃拉托斯特尼筛法),卢卡斯-莱默检验法和AKS素数测试。
常见的随机方法有费马素性检验,米勒-拉宾检验和欧拉-雅科比测试。
本次作业采用就是米勒-拉宾检验方法。
米勒-拉宾(Miller Rabin) 算法原理:要测试N 是否为素数,首先将N-1 分解为2s d。
在每次测试开始时,先随机选一个介于[1, N-1]的整数a,之后如果对所有的r∈[0, s-1],若a d mod N ≠ 1 且a2^rd mod N ≠1,则N 是合数。
否则,N 有3/4 的概率为素数。
1.3安全问题(1)公共模数攻击。
每个人具有相同的r,但有不同的指数e和d,这是不安全的。
(2)低加密指数攻击。
如果选择了较低的e值,虽然可以加快计算速度,但存在不安全性。
(3)低解密指数攻击。
如果选择了较低的d值,也是不安全的。
(4)选择密文攻击。
如A想让T对一个T不愿意签名的消息m’签名,A首先选择一个任意值x,计算y=x e(mod r),然后要求T对m=ym’签名,A最后计算(m d mod r)x-1 mod r =( ym’) d x-1mod r= m’d mod r。
还有一些不是直接对RSA的算法本身进行的攻击,如中间人攻击、时间攻击、边信道攻击等。
2.具体实现2.1函数说明void ProducePrime(JTextField prime):使用JA V A的Biginteger生成512位的大数,再用Miller Robin算法检验是否是素数。
参数prime即为生成的大素数。
boolean MillerRobin(BigInteger n):用Miller Robin检验判断大数n是否是素数。
BigInteger modex(BigInteger a, BigInteger b, BigInteger n):模幂运算,计算a b mod nBigInteger inverse(BigInteger a, BigInteger b):求逆运算,计算a-1 ( b )String Encode(String Plaintext, BigInteger n, int nLen, int m, JTextField e):加密,用公钥(n,e)对明文Plaintext加密。
String Decode(String Ciphertext, BigInteger n, int m, JTextField d):解密,用私钥d对密文Ciphertext解密。
2.2JA V A代码import java.math.BigInteger;import java.util.Random;import java.util.Scanner;import javax.swing.JTextField;public class RSA {public static void main(String[] args) {String s;JTextField p = new JTextField(35);JTextField q = new JTextField(35);JTextField e = new JTextField(35);JTextField d = new JTextField(35);ProducePrime(p);ProducePrime(q);BigInteger pp = new BigInteger(p.getText());BigInteger qq = new BigInteger(q.getText());BigInteger oo = (pp.subtract(new BigInteger("1"))).multiply(qq.subtract(new BigInteger("1")));BigInteger ee;do {ee = new BigInteger(100, new Random()).mod(oo);} while (MillerRobin(ee) == false);e.setText(ee.toString());d.setText(inverse(ee, oo).toString());BigInteger n = pp.multiply(qq);int nLen = n.bitLength();int m = (int) (Math.ceil((double) (nLen) / 16.0));nLen = (nLen - 1) / 16;String Ciphertext = new String();String Plaintext = new String();System.out.println("P:" + p.getText());System.out.println("Q:" + q.getText());System.out.println("公钥:" + e.getText());System.out.println("私钥:" + d.getText());Scanner scanner = new Scanner(System.in);System.out.println("输入要加密字符串:");s = scanner.nextLine();Ciphertext = Encode(s, n, nLen, m, e);System.out.println("加密结果:" + Ciphertext);Plaintext = Decode(Ciphertext, n, m, d);System.out.println("解密结果:" + Plaintext);}//产生大素数public static void ProducePrime(JTextField prime) {BigInteger n = new BigInteger("0");Random r = new Random();do {n = new BigInteger(512, 5, r);prime.setText(n.toString());} while (MillerRobin(n) == false);}//Miller Robin素性检验public static boolean MillerRobin(BigInteger n) {int time = 1000;BigInteger m = n.mod(new BigInteger("2"));if (m.equals(new BigInteger("0"))) {return false;}int s = 0;int k = 0;BigInteger t = n.subtract(new BigInteger("1"));while (t.mod(new BigInteger("2")).equals("0")) {t.divide(new BigInteger("2"));++s;}for (int i = 0; i < time; ++i) {BigInteger a = new BigInteger(100, new Random()).mod(n.subtract(new BigInteger("3"))).add(new BigInteger("2"));BigInteger b = modex(a, t, n);if (b.equals(new BigInteger("1")) == false&& b.equals(n.subtract(new BigInteger("1"))) == false) {k = 1;while (k == s&& b.equals(n.subtract(new BigInteger("1"))) == false) {b = b.multiply(b).mod(n);if (b.equals(new BigInteger("1"))) {return false;}++k;}if (b.equals(n.subtract(new BigInteger("1"))) == false) {return false;}}}return true;}//模幂运算public static BigInteger modex(BigInteger a, BigInteger b, BigInteger n) {BigInteger m = new BigInteger("1");while (b.equals(new BigInteger("0")) == false) {if (b.mod(new BigInteger("2")).equals(new BigInteger("1"))) {m = m.multiply(a).mod(n);}a = a.multiply(a).mod(n);b = b.divide(new BigInteger("2"));}return m;}//求逆运算public static BigInteger inverse(BigInteger a, BigInteger b) {BigInteger n1 , n2 , n3, m, t, b1;n1 = new BigInteger("1");n2 = new BigInteger("0");b1 = b;while (b.equals(new BigInteger("0")) == false) {m = a.divide(b);n3 = n1.subtract(m.multiply(n2));if (pareTo(new BigInteger("0")) != -1) {n3 = n3.mod(b1);} else {n3 = b1.subtract(n3.multiply(new BigInteger("-1")).mod(b1));}n1 = n2;n2 = n3;t = b;b = a.mod(b);a = t;}if (a.equals(new BigInteger("1"))) {return n1;} else {return new BigInteger("0");}}//加密public static String Encode(String Plaintext, BigInteger n, int nLen, int m, JTextField e) {BigInteger r = new BigInteger("0");StringBuffer outBuf = new StringBuffer();int i, j, k;for (i = 0; i < Plaintext.length(); i = j) {BigInteger t = new BigInteger("0");for (j = i; j < i + nLen && j < Plaintext.length(); j++) {t = t.shiftLeft(16);long num = Plaintext.charAt(j);t = t.add(BigInteger.valueOf(num));}r = modex(t, new BigInteger(e.getText()), n);String buf = new String();for (k = 0; k < m; ++k) {long num = (r.and(BigInteger.valueOf(65535))).longValue();r = r.shiftRight(16);buf = (char) (num) + buf;}outBuf = outBuf.append(buf);}return outBuf.toString();}//解密public static String Decode(String Ciphertext, BigInteger n, int m, JTextField d) {StringBuffer outBuf = new StringBuffer();BigInteger r = new BigInteger("0");int i, j;for (i = 0; i < Ciphertext.length(); i += j) {BigInteger t = new BigInteger("0");for (j = 0; j < m && j + i < Ciphertext.length(); j++) {t = t.shiftLeft(16);long num = (long) (Ciphertext.charAt(j + i));t = t.add(BigInteger.valueOf(num));}r = modex(t, new BigInteger(d.getText()), n);String buf = new String();while (pareTo(new BigInteger("0")) > 0) {long num = (r.and(BigInteger.valueOf(65535))).longValue();buf = (char) (num) + buf;r = r.shiftRight(16);}outBuf = outBuf.append(buf);}return outBuf.toString();}}2.3测试结果:P:129036805470851517375614397900032888596537198498489613936254861169557 280794177755476583936161903531948987784914983448340462980850402666689 13843973354103033Q:965485259575386626661798155084845386764376902206479716964206598369971506074458894922536120328881558956967066309443036648783409751809379053 0180407555360339公钥:1133142713903219484415537969751私钥:289229897767689634195491655141643249544903709281685759316055760288297 329286785308503278756568252277106589199437078007305924525623679341478 908797523966221390308041636992564515935685594854485373424597837714855 144013790195492262743427356815741901651405003362999246563628660918125 34177904849175286307833237971415输入要加密字符串:密码学算法RSA加密结果:偮钘?兄埅????烄証箕???霑痘????啛猝市????鎈????釤?????????????筕???酪? ??霧?羳???鑮だ解密结果:密码学算法RSA。