RSA算法(非对称加密)

一、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;
    }

}

 

posted @ 2018-03-25 15:06  little——boy  阅读(641)  评论(0编辑  收藏  举报