为了加密一个消息P,只要计算C=P^e(mod n) 即可。为了解密C,只要计算P=C^d(mod n)即可。可以证明,对于指定范围内的所有P,加密盒解密互为反函数。为了执行加密,你需要e和n;为了执行解密,你需要d和n。因此,公钥是有(e,n)对组成,而私钥是有(d,n)对组成。
实例:根据已知参数:p=3,q=11,M=2,计算公私钥,并对明文进行加密,然后对密文进行解密。
由题意知:n = p * q=33,z =(p-1)*(q-1)=20,选d=7,
计算得e=3,所以
C=M^e(mod n)=8
M=C^d(mod n)=2
2、RSA算法与DES算法的比较:
运行附件的RSATool,输入一大段文字,记录运行时间。再使用DES算法加密相同的文字,记录运行时间,对比这两个时间发现,RSA算法比DES算法慢很多,因为RSA算法进行的是大数运算,所以程序运行的速度比DES慢很多。因此RSA算法只适合于少量数据加密,不适合于大量数据加密。
3、算法设计
主要的方法:
(1)、public static void GetPrime()
方法名称:产生大数的方法。
说明:
利用Java语言的中的java.math.BigInteger类的方法中随机产生大数。(2)、public static boolean MillerRobin(BigInteger num)
方法名称:判断是否是素数的方法。
参数说明:
num是由GetPrime方法产生的大数。
说明:
这个方法判断GetPrime方法传过来的是否是一个素数,是就返回true,否就返回false。
(3)、public static BigInteger powmod( BigInteger a, BigInteger t, BigInteger num ) 方法名称:大数的幂运算方法。
说明:
这个方法对传入的大数进行幂运算。
(4)、public static BigInteger invmod(BigInteger a, BigInteger b)
方法名称:大数的取模运算方法。
说明:这个方法对大数进行取模运算。
(5)、public static String Encode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,
BigInteger n,int nLen,int m,JTextField d) 方法名称:加密算法。
参数说明:
inStr是从界面输入的明文。
PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。
n是由PrimeP和PrimeQ得到的值。
nLen为n的长度。
d为公钥。
(6)、public static String Decode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,
BigInteger n,int nLen,int m,JTextField e) 方法名称:解密算法。
参数说明:
inStr是从界面输入的明文。
PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。
n是由PrimeP和PrimeQ得到的值。
nLen为n的长度。
e为私钥。
4、源程序:(RSA1.java文件)
import javax.swing.*;
import java.awt.event.*;
import java.math.*;
import java.util.*;
import java.awt.*;
import java.io.*;
public class RSA1{
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
MyPanel_fbutton panel_fbutton = new MyPanel_fbutton(frame,frame.P,frame.Q,frame.d,frame.e);
FlowLayout fl = new FlowLayout (FlowLayout.CENTER,0,0);
frame.setLayout(fl);
frame.add(panel_fbutton);
frame.setBounds( 150, 100, 500, 480 );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class MyFrame extends JFrame
{
public MyFrame()
{
setTitle("RSA算法");
add(wel);
MyPanel_p panel_p = new MyPanel_p(P);
add(panel_p);
MyPanel_q panel_q = new MyPanel_q(Q);
add(panel_q);
MyPanel_d panel_d = new MyPanel_d(d);
add(panel_d);
MyPanel_e panel_e = new MyPanel_e(e);
add(panel_e);
MyPanel_in panel_in = new MyPanel_in(input);
add(panel_in);
MyPanel_out panel_out = new MyPanel_out(output);
add(panel_out);
MyPanel_out1 panel_out1 = new MyPanel_out1(output1);
add(panel_out1);
MyPanel_button panel_button = new MyPanel_button(P,Q,d,e,input,output,output1);
add(panel_button);
}
private JLabel wel = new JLabel(" RSA算法演示");
protected JTextField P = new JTextField(35);
protected JTextField Q = new JTextField(35);
protected JTextField d = new JTextField(35);
protected JTextField e = new JTextField(35);
protected JTextArea input = new JTextArea(4,35);
protected JTextArea output = new JTextArea(4,35);
protected JTextArea output1 = new JTextArea(4,35);
}
class MyPanel_fbutton extends JPanel
{
public MyPanel_fbutton(Frame aframe,JTextField aP, JTextField aQ, JTextField ad, JTextField ae)
{
frame = aframe;
P = aP;
Q = aQ;
e = ae;
d = ad;
}
private Frame frame;
private JTextField P;
private JTextField Q;
private JTextField d;
private JTextField e;
}
class MyPanel_p extends JPanel
{
public MyPanel_p(JTextField aP)
{
P=aP;
add(new JLabel(" 质数P:"));
add(P);
}
private JTextField P;
}
class MyPanel_q extends JPanel
{
public MyPanel_q(JTextField aQ)
{
Q=aQ;
add(new JLabel(" 质数Q:"));
add(Q);
}
private JTextField Q;
}
class MyPanel_d extends JPanel
{
public MyPanel_d(JTextField ad)
{
d=ad;
add(new JLabel(" 公钥:"));
add(d);
}
private JTextField d;
}
class MyPanel_e extends JPanel
{
public MyPanel_e(JTextField ae)
{
e=ae;
add(new JLabel(" 私钥:"));
add(e);
}
private JTextField e;
}
class MyPanel_in extends JPanel
{
public MyPanel_in(JTextArea ainput)
{
input = ainput;
add(new JLabel(" 输入明文:"));
JScrollPane jsp1 = new JScrollPane (input,v,h);
add(jsp1);
}
private JTextArea input;
int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;
int h=JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED; }
class MyPanel_out extends JPanel
{
public MyPanel_out(JTextArea aoutput)
{
output = aoutput;
add(new JLabel(" 生成的密文:"));
JScrollPane jsp = new JScrollPane (output,v,h);
add(jsp);
}
private JTextArea output;
int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;
int h=JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;
}
class MyPanel_out1 extends JPanel
{
public MyPanel_out1(JTextArea aoutput1)
{
output1 = aoutput1;
add(new JLabel("解密后的明文:"));
JScrollPane jsp = new JScrollPane (output1,v,h);
add(jsp);
}
private JTextArea output1;
int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;
int h=JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
}
class MyPanel_button extends JPanel
{
public MyPanel_button(JTextField aP,JTextField aQ,JTextField ad,JTextField ae,
JTextArea ainput,JTextArea aoutput,JTextArea aoutput1) {
P = aP;
Q = aQ;
e = ae;
d = ad;
input = ainput ;
output = aoutput ;
output1 = aoutput1 ;
randProduce.addActionListener(new RandListener( P, Q ));
add(randProduce);
randD.addActionListener(new RandDListener( P, Q, d, e ));
add(randD);
encode.addActionListener(new EncodeListener( P, Q, d, e, input, output ));
add(encode);
decode.addActionListener(new DecodeListener( P, Q, d, e, output, output1 ));
add(decode);
}
private JTextField P;
private JTextField Q;
private JTextField d;
private JTextField e;
private JTextArea input;
private JTextArea output;
private JTextArea output1;
private JButton randProduce = new JButton("生成质数P和Q");
private JButton randD = new JButton("生成公钥和私钥");
private JButton encode = new JButton("加密");
private JButton decode = new JButton("解密");
}
class FileEncodeListener implements ActionListener
{
public FileEncodeListener(Frame f,JTextField ap, JTextField aq,JTextField ae,JTextField ad) {
P = ap;
Q = aq;
E = ae;
D = ad;
fr = f;
}
public void actionPerformed(ActionEvent ee)
{
FileDialog fd = new FileDialog(fr);
fd.setVisible(true);
String infileName =fd.getDirectory()+fd.getFile();
String inStr = new String();
inStr = PublicMethod.read(infileName);
BigInteger PrimeP = new BigInteger(P.getText());
BigInteger PrimeQ = new BigInteger(Q.getText());
BigInteger n =PrimeP.multiply(PrimeQ);
int nLen = n.bitLength();
int m=(int)(Math.ceil((double)(nLen)/16.0));
nLen = (nLen-1) / 16;
String outStr = new String();
outStr = PublicMethod.Encode(inStr,PrimeP,PrimeQ,n,nLen,m,D);
for(i=infileName.length()-1;i>=0;--i)
{
if(infileName.charAt(i)=='.') break;
}
String outfileName = infileName.substring(0,i);
outfileName = outfileName + new String(".EncodeRsa") + infileName.substring(i,infileName.length());
PublicMethod.output(outfileName,outStr);
}
private JTextField P;
private JTextField Q;
private JTextField E;
private JTextField D;
private Frame fr;
int i;
}
class FileDecodeListener implements ActionListener
{
public FileDecodeListener(Frame f,JTextField ap, JTextField aq,JTextField ae,JTextField ad)
{
P = ap;
Q = aq;
E = ae;
D = ad;
fr = f;
}
public void actionPerformed(ActionEvent ee)
{
FileDialog fd = new FileDialog(fr);
fd.setVisible(true);
String infileName =fd.getDirectory()+fd.getFile();
String inStr = new String();
inStr = PublicMethod.input(infileName);
System.out.println(inStr);
BigInteger PrimeP = new BigInteger(P.getText());
BigInteger PrimeQ = new BigInteger(Q.getText());
BigInteger n =PrimeP.multiply(PrimeQ);
int nLen = n.bitLength();
int m=(int)(Math.ceil((double)(nLen)/16.0));
nLen = (nLen-1) / 16;
String outStr = new String();
outStr = PublicMethod.Decode(inStr,PrimeP,PrimeQ,n,nLen,m,E);
for(i=infileName.length()-1;i>=0;--i)
{
if(infileName.charAt(i)=='.') break;
}
String outfileName = infileName.substring(0,i);
outfileName = outfileName + new String(".DecodeRsa") + infileName.substring(i,infileName.length());
PublicMethod.write(outfileName,outStr);
}
private JTextField P;
private JTextField Q;
private JTextField E;
private JTextField D;
private Frame fr;
int i;
}
class RandListener implements ActionListener
{
public RandListener(JTextField aP, JTextField aQ)
{
P = aP;
Q = aQ;
}
public void actionPerformed(ActionEvent e)
{
PublicMethod.GetPrime( P );
PublicMethod.GetPrime( Q );
}
private JTextField P;
private JTextField Q;
}
class RandDListener implements ActionListener
{
public RandDListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae)
{
P = aP;
Q = aQ;
d = ad;
e = ae;
}
public void actionPerformed(ActionEvent ee)
{
BigInteger PP = new BigInteger(P.getText());
BigInteger QQ = new BigInteger(Q.getText());
BigInteger temp = (PP.subtract(new BigInteger("1"))).multiply(QQ.subtract(new BigInteger("1")));
BigInteger temp1;
do
{
temp1=new BigInteger(100, new Random()).mod(temp);
}
while(https://www.360docs.net/doc/0216435215.html,lerRobin(temp1)==false);
d.setText(temp1.toString());
e.setText(PublicMethod.invmod(temp1, temp).toString());
}
private JTextField P;
private JTextField Q;
private JTextField d;
private JTextField e;
}
class EncodeListener implements ActionListener
{
public EncodeListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae,
JTextArea in, JTextArea out)
{
P = aP;
Q = aQ;
d = ad;
e = ae;
input = in;
output = out;
}
public void actionPerformed(ActionEvent ee)
{
BigInteger PrimeP = new BigInteger(P.getText());
BigInteger PrimeQ = new BigInteger(Q.getText());
BigInteger n =PrimeP.multiply(PrimeQ);
int nLen = n.bitLength();
int m=(int)(Math.ceil((double)(nLen)/16.0));
nLen = (nLen-1) / 16;
String inStr = input.getText();
output.setText(PublicMethod.Encode(inStr,PrimeP,PrimeQ,n,nLen,m,e));
}
private JTextField P;
private JTextField Q;
private JTextField d;
private JTextField e;
private JTextArea input;
private JTextArea output;
}
class DecodeListener implements ActionListener
{
public DecodeListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae, JTextArea out, JTextArea out1)
{
P = aP;
Q = aQ;
d = ad;
e = ae;
output = out;
output1 = out1;
}
public void actionPerformed(ActionEvent ee)
{
BigInteger PrimeP = new BigInteger(P.getText());
BigInteger PrimeQ = new BigInteger(Q.getText());
BigInteger n =PrimeP.multiply(PrimeQ);
int nLen = n.bitLength();
int m=(int)(Math.ceil((double)(nLen)/16.0));
nLen = (nLen-1) / 16;
String inStr = output.getText();
output1.setText(PublicMethod.Decode(inStr,PrimeP,PrimeQ,n,nLen,m,d));
}
private JTextField P;
private JTextField Q;
private JTextField d;
private JTextField e;
private JTextArea output;
private JTextArea output1;
}
class PublicMethod
{
public static void GetPrime( JTextField prime )
{
BigInteger num = new BigInteger("0");
Random rand = new Random();
do
{
int length = (int)(Math.random()*20+100);
System.out.println(length);
num = new BigInteger( length, 5 , rand );
prime.setText(num.toString());
}
while(MillerRobin(num)==false);
}
public static boolean MillerRobin(BigInteger num)
{
int time = 1000;
BigInteger mod = num.mod(new BigInteger("2"));
if(mod.equals(new BigInteger("0")))
{
return false;
}
int s = 0, j=0;
BigInteger t=num.subtract(new BigInteger("1"));
while( t.mod(new BigInteger("2")).equals("0") )
{
t.divide(new BigInteger("2"));
++s;
}
for(int i=0; i