一、RSA算法
1、密钥对生成过程
1)、寻找两个质数p和q,使得n = p*q;
2)、计算L = (p-1)(q-1);
3)、选择一个1到L的整数e,使得e与L为互质数。即gcd(L,e) = 1;
4)、根据d*e mod L = 1,计算数字d;
5)、那么(e,n)为公钥,(d,n)为私钥。
2、加密:C=(M^e)modN,(M<n)利用分组的方式将长的密文加密或者解密。
3、解密:M=(C^d)modN
4、C=(a^k)modM
1 long mi(long a,long k,long M) 2 { 3 long b=1; 4 while(k>=1){ 5 if(k%2==1){ 6 b=a*b%M; 7 } 8 a=(a%M)*(a%M)%M; 9 k/=2; 10 } 11 return b; 12 }
public class RSA { public static void main(String[] args) { // TODO Auto-generated method stub new MyWindow(); } }
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.math.*; import java.util.*; /** * * @author IBM */ public class MyWindow extends JFrame implements ActionListener { private JLabel label, _label, __label, klabel; private JTextField fileName, _fileName, __fileName, kfileName; private JButton open, _open, __open, kopen; private JButton begin; private JLabel title; private JTextArea message; String tName, tPath; String _tName, _tPath; String __tName, __tPath; String kName, kPath; public MyWindow() { super("64bit RSA"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(false); label = new JLabel("请输入明文文件 "); _label = new JLabel("请输入密文输出文件"); __label = new JLabel("请输入解密输出文件"); klabel = new JLabel("请输入密钥输出文件"); open = new JButton("open..."); _open = new JButton("open..."); __open = new JButton("open..."); kopen = new JButton("open..."); fileName = new JTextField(); fileName.setColumns(16); _fileName = new JTextField(); _fileName.setColumns(16); __fileName = new JTextField(); __fileName.setColumns(16); kfileName = new JTextField(); kfileName.setColumns(16); open.addActionListener(new OpenL()); _open.addActionListener(new SaveL()); __open.addActionListener(new SaveR()); kopen.addActionListener(new SaveK()); begin = new JButton("开始工作"); title = new JLabel("工作方式:"); message = new JTextArea(); message.setSize(16, 10); message.setEditable(false); begin.addActionListener(this); setLayout(null); add(label); label.setBounds(10, 10, 280, 20); add(fileName); fileName.setBounds(10, 40, 170, 20); add(open); open.setBounds(200, 40, 80, 20); add(_label); _label.setBounds(10, 80, 280, 20); add(_fileName); _fileName.setBounds(10, 110, 170, 20); add(_open); _open.setBounds(200, 110, 80, 20); add(__label); __label.setBounds(10, 150, 280, 20); add(__fileName); __fileName.setBounds(10, 180, 170, 20); add(__open); __open.setBounds(200, 180, 80, 20); add(klabel); klabel.setBounds(10, 220, 280, 20); add(kfileName); kfileName.setBounds(10, 250, 170, 20); add(kopen); kopen.setBounds(200, 250, 80, 20); message.setEditable(false); message.setLineWrap(true); message.setText(""); message.append("Alice向Bob发送一条加密信息:\n"); message.append("1. Bob生成公钥与私钥,密钥输出文件包含了该信息;\n"); message.append("2. Alice从明文文件中读入明文,并用Bob提供的公钥进行加密,密文输出文件包含了该信息;\n"); message.append("3. Alice将密文传给Bob;\n"); message.append("4. Bob利用自己的私钥解密文件,获得信息,解密输出文件包含了该信息;\n"); message.append("工作结束。"); add(title); title.setBounds(10, 300, 280, 20); add(message); message.setBounds(10,330, 280, 170); add(begin); begin.setBounds(100, 520, 100, 40); setBounds(100, 100, 300, 600); setVisible(true); validate(); } class OpenL implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); int rVal = c.showOpenDialog(MyWindow.this); if (rVal == JFileChooser.APPROVE_OPTION) { tName = c.getSelectedFile().getName(); tPath = c.getCurrentDirectory().toString(); if (!tPath.endsWith(new String("/"))) { tPath = tPath.concat(new String("/")); } fileName.setText(tPath + tName); } } } class SaveL implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); int rVal = c.showSaveDialog(MyWindow.this); if (rVal == JFileChooser.APPROVE_OPTION) { _tName = c.getSelectedFile().getName(); _tPath = c.getCurrentDirectory().toString(); if (!_tPath.endsWith(new String("/"))) { _tPath = _tPath.concat(new String("/")); } _fileName.setText(_tPath + _tName); } } } class SaveR implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); int rVal = c.showSaveDialog(MyWindow.this); if (rVal == JFileChooser.APPROVE_OPTION) { __tName = c.getSelectedFile().getName(); __tPath = c.getCurrentDirectory().toString(); if (!__tPath.endsWith(new String("/"))) { __tPath = __tPath.concat(new String("/")); } __fileName.setText(__tPath + __tName); } } } class SaveK implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); int rVal = c.showSaveDialog(MyWindow.this); if (rVal == JFileChooser.APPROVE_OPTION) { kName = c.getSelectedFile().getName(); kPath = c.getCurrentDirectory().toString(); if (!kPath.endsWith(new String("/"))) { kPath = kPath.concat(new String("/")); } kfileName.setText(kPath + kName); } } } public void actionPerformed(ActionEvent e) { String input = ""; String output = ""; open.setEnabled(false); _open.setEnabled(false); __open.setEnabled(false); kopen.setEnabled(false); begin.setEnabled(false); validate(); Bob bob = new Bob(); Alice alice = new Alice(bob); //message.append("Alice向Bob发送一条加密信息:\n"); try { PrintWriter out = new PrintWriter(kfileName.getText()); Key key = bob.getKey(); out.println("Public Key a:"); out.println(key.a); out.println(); out.println("Public Key n:"); out.println(key.n); out.println(); out.println("Private Key b:"); out.println(key.b); out.println(); out.println("Private Key p:"); out.println(key.p); out.println(); out.println("Private Key q:"); out.println(key.q); out.close(); } catch (Exception e3) { JOptionPane.showMessageDialog(this, "输出文件错误", "错误", JOptionPane.ERROR_MESSAGE); errorOUT(); return; } //message.append("Bob生成密钥,密钥输出至密钥输出文件。\n"); //message.append("Alice从明文文件中读入明文...\n"); input = ""; try { File f = new File(tPath, tName); String temp = new String(""); BufferedReader in = new BufferedReader(new FileReader(fileName.getText())); StringBuilder sb = new StringBuilder(); while ((temp = in.readLine()) != null) { input = input + temp; } in.close(); } catch (Exception ee) { JOptionPane.showMessageDialog(this, "输入文件错误", "错误", JOptionPane.ERROR_MESSAGE); errorOUT(); return; } //message.append("Alice利用Bob提供的公钥对明文进行加密...\n"); while (input.length() % 64 != 0) input = input + "0"; int len = input.length(); output = ""; try { PrintWriter out = new PrintWriter(_fileName.getText()); for (int i = 0; i < len; i += 64) { BigInteger x = BigInteger.ZERO; for (int j = 0; j < 64; ++j) { x = x.multiply(new BigInteger("2")); if (input.charAt(i + j) == '1') x = x.add(BigInteger.ONE); } alice.setM(x); BigInteger y = alice.getC(); bob.receiveMessage(alice.getC()); BigInteger z = bob.getM(); String temp = ""; while (y.compareTo(BigInteger.ZERO) != 0) { if (y.remainder(new BigInteger("2")).compareTo(BigInteger.ONE) == 0) { temp = "1" + temp; } else { temp = "0" + temp; } y = y.divide(new BigInteger("2")); } out.print(temp + " "); temp = ""; while (z.compareTo(BigInteger.ZERO) != 0) { if (z.remainder(new BigInteger("2")).compareTo(BigInteger.ONE) == 0) { temp = "1" + temp; } else { temp = "0" + temp; } z = z.divide(new BigInteger("2")); } while (temp.length() != 64) temp = "0" + temp; output = output + temp; } out.close(); } catch (Exception e2) { JOptionPane.showMessageDialog(this, "输出文件错误", "错误", JOptionPane.ERROR_MESSAGE); errorOUT(); return; } //message.append("Alice对文件加密结束。密文文件输出值密文输出文件。\n"); //message.append("Bob接收密文,并用私钥进行解密。\n"); try { PrintWriter out = new PrintWriter(__fileName.getText()); out.println(output); out.close(); } catch (Exception e1) { JOptionPane.showMessageDialog(this, "输出文件错误", "错误", JOptionPane.ERROR_MESSAGE); errorOUT(); return; } //message.append("Bob解密后的明文输出至明文输出文件\n"); //message.append("信息传输过程结束。"); JOptionPane.showMessageDialog(this, "工作完成!", "完成", JOptionPane.INFORMATION_MESSAGE); open.setEnabled(true); _open.setEnabled(true); __open.setEnabled(true); kopen.setEnabled(true); begin.setEnabled(true); } private void errorOUT() { open.setEnabled(true); _open.setEnabled(true); __open.setEnabled(true); kopen.setEnabled(true); begin.setEnabled(true); } }
import java.math.*; /** * * @author IBM */ public class Alice { private BigInteger M, C; private Bob bob; public Alice(Bob bob) { this.bob = bob; } private void encrypt() { BigInteger b = bob.getKeyB(); BigInteger n = bob.getKeyN(); C = pow(M, b, n); } public void setM(BigInteger m) { M = m; encrypt(); } public BigInteger getC() { return C; } private BigInteger pow(BigInteger x, BigInteger a, BigInteger d) { if (a.compareTo(BigInteger.ZERO) == 0) return new BigInteger("1"); if (a.compareTo(BigInteger.ONE) == 0) return x.remainder(d); BigInteger ans = pow(x, a.divide(new BigInteger("2")), d); if (a.remainder(new BigInteger("2")).compareTo(BigInteger.ZERO) == 0) { ans = ans.multiply(ans).remainder(d); } else { ans = ans.multiply(ans).multiply(x).remainder(d); } return ans; } }
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.math.*; import java.util.*; /** * * @author IBM */ public class Key { public BigInteger p, q; public BigInteger n; public BigInteger eularN; public BigInteger a, b; private final int RAND_N = 30000; private final int RABIN_S = 50; private final int PRIME_N = 512; public Key() { p = pseudoprimeGenerate(PRIME_N); q = pseudoprimeGenerate(PRIME_N); n = p.multiply(q); eularN = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); while (true) { b = oddGenerate(2 * PRIME_N - 1); //Extended Euclidean Algorithm(eularN, b) BigInteger a0 = eularN; BigInteger b0 = b; BigInteger t0 = BigInteger.ZERO; BigInteger t = BigInteger.ONE; BigInteger s0 = BigInteger.ONE; BigInteger s = BigInteger.ZERO; BigInteger tq = a0.divide(b0); BigInteger r = a0.subtract(tq.multiply(b0)); while (r.compareTo(BigInteger.ZERO) > 0) { BigInteger temp = t0.subtract(tq.multiply(t)); t0 = t; t = temp; s0 = s; s = temp; a0 = b0; b0 = r; tq = a0.divide(b0); r = a0.subtract(tq.multiply(b0)); } r = b0; if (r.compareTo(BigInteger.ONE) != 0) continue; else { a = t; if (a.compareTo(BigInteger.ZERO) > 0) { a = a.remainder(eularN); } else { BigInteger tempA = BigInteger.ZERO.subtract(a); BigInteger l = tempA.divide(eularN).add(new BigInteger("2")); a = a.add(eularN.multiply(l)).remainder(eularN); } break; } } } //y = x^a mod d private BigInteger pow(BigInteger x, BigInteger a, BigInteger d) { if (a.compareTo(BigInteger.ZERO) == 0) return new BigInteger("1"); if (a.compareTo(BigInteger.ONE) == 0) return x.remainder(d); BigInteger ans = pow(x, a.divide(new BigInteger("2")), d); if (a.remainder(new BigInteger("2")).compareTo(BigInteger.ZERO) == 0) { ans = ans.multiply(ans).remainder(d); } else { ans = ans.multiply(ans).multiply(x).remainder(d); } return ans; } //Miller-Rabin Check private boolean MillerRabin(BigInteger n) { BigInteger m = n.subtract(BigInteger.ONE); int k = 0; while (m.remainder(new BigInteger("2")).compareTo(BigInteger.ZERO) == 0) { m = m.divide(new BigInteger("2")); ++k; } Random ranGenerator = new Random(); int _a = ranGenerator.nextInt(RAND_N) + 1; BigInteger a = new BigInteger(String.valueOf(_a)); BigInteger b = pow(a, m, n); if (b.compareTo(BigInteger.ONE) == 0) return true; for (int i = 0; i < k; ++i) { if (b.compareTo(n.subtract(BigInteger.ONE)) == 0) return true; b = b.multiply(b).remainder(n); } return false; } //Generate a bits-bit pseudoprime private boolean pseodoprime[]; private BigInteger pseudoprimeGenerate(int bits) { pseodoprime = new boolean[bits]; Random ranGenerator = new Random(); while (true) { pseodoprime[0] = true; for (int i = 1; i < bits - 1; ++i) { pseodoprime[i] = ranGenerator.nextBoolean(); } pseodoprime[bits - 1] = true; BigInteger x = new BigInteger("0"); for (int i = 0; i < bits; ++i) { x = x.multiply(new BigInteger("2")); if (pseodoprime[i]) x = x.add(BigInteger.ONE); } boolean ok = true; for (int i = 0; i < RABIN_S; ++i) { if (!MillerRabin(x)) { ok = false; break; } } if (ok) return x; } } private boolean odd[]; private BigInteger oddGenerate(int bits) { odd = new boolean[bits]; Random ranGenerator = new Random(); for (int i = 0; i < bits - 1; ++i) { odd[i] = ranGenerator.nextBoolean(); } odd[bits - 1] = true; BigInteger x = new BigInteger("0"); for (int i = 0; i < bits - 1; ++i) { x = x.multiply(new BigInteger("2")); if (odd[i]) x = x.add(BigInteger.ONE); } return x; } }
import java.math.*; /** * * @author IBM */ public class Bob { private Key key; private BigInteger M; private BigInteger C; public Bob() { key = new Key(); } public void receiveMessage(BigInteger c) { C = c; M = pow(C, key.a, key.n); } public BigInteger getM() { return M; } //public key: b public BigInteger getKeyB() { return key.b; } //public key: a public BigInteger getKeyN() { return key.n; } public Key getKey() { return key; } private BigInteger pow(BigInteger x, BigInteger a, BigInteger d) { if (a.compareTo(BigInteger.ZERO) == 0) return new BigInteger("1"); if (a.compareTo(BigInteger.ONE) == 0) return x.remainder(d); BigInteger ans = pow(x, a.divide(new BigInteger("2")), d); if (a.remainder(new BigInteger("2")).compareTo(BigInteger.ZERO) == 0) { ans = ans.multiply(ans).remainder(d); } else { ans = ans.multiply(ans).multiply(x).remainder(d); } return ans; } }