⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa.java

📁 未使用任何开发包的RSA算法
💻 JAVA
字号:
/**
 * 本程序实现对文件进行非对称RSA加密
 * 版权所有@计算机科学学院 何文
 * 注意:在点击按钮“随机产生后”如果n的值小于65535,或者大于131072时,需要再次点击按钮,直到n值符合条件
 * 加密后产生的文件为源文件名相同但后缀为encrypt的文件,文件与源文件在同一个目录下
 * 解密后产生的文件为源文件名相同但后缀为decrypt的文件,文件与源文件在同一个目录下
 */
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import java.lang.Double;
import java.awt.Color;
import javax.swing.BorderFactory;
import java.math.*;

 
public class RSA extends JFrame
{
	public static final int WIDTH = 550; 
	public static final int HEIGHT = 200; 
	keyPanel pp;
	Container c;
	
	//主函数
	public static void main(String args[])
	{
		new RSA();
	}
	
	//构造函数
	public RSA()
	{
		this.setSize(WIDTH,HEIGHT); 
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		this.setResizable(false); 
		Toolkit tk = Toolkit.getDefaultToolkit(); 
		Dimension screenSize = tk.getScreenSize(); 
		this.setLocation((screenSize.width - WIDTH)/2, 
		(screenSize.height - HEIGHT)/2); 
		this.setTitle("文件加密器(TriDES)"); 
		c = this.getContentPane(); 
		c.setLayout( new FlowLayout()); 

		final FilePanel fp = new FilePanel("文件选择"); 
		c.add(fp); 
		pp = new keyPanel(); 
		c.add(pp); 
		JButton jbE = new JButton("加密"); 
		c.add(jbE); 
		
		jbE.addActionListener(new ActionListener(){    //侦听函数
		public void actionPerformed(ActionEvent event)
		{ 
			System.out.println((int)RSAcrypt(8831,70871,-213));
			System.out.println(RSAcrypt(40271,70871,-2035));
			try{
				File f = new File(fp.getFileName());
				int length = (int)f.length();
				int[] data = new int[length/2];
				short[] OutPut = new short[length/2];
				DataInputStream in = new DataInputStream(new FileInputStream(f));
				DataOutputStream out = new DataOutputStream(new FileOutputStream(f+".encrypt"));
				for(int i=0;i<length/2;i++)
				{
					data[i]=in.readUnsignedShort();
				}
				OutPut = crypt(Integer.valueOf(pp.fileText3.getText()).intValue(),Integer.valueOf(pp.fileText4.getText()).intValue(),data);
				for(int i=0;i<length/2;i++)
				{
					out.writeShort((int)OutPut[i]);
				}
				out.flush();
				out.close();
				in.close();
				}catch(IOException IOE){}
				JOptionPane.showMessageDialog( c,"加密成功!"); 
		} 
		}); 
			JButton jbD = new JButton("解密"); 
			c.add(jbD); 
		jbD.addActionListener(new ActionListener()
		{ 
			public void actionPerformed(ActionEvent event)
			{ 
				try{
					File f = new File(fp.getFileName());
					int length = (int)f.length();
					int[] data = new int[length/2];
					short[] OutPut = new short[length/2];
					DataInputStream in = new DataInputStream(new FileInputStream(f));
					DataOutputStream out = new DataOutputStream(new FileOutputStream(f+".decrypt"));
					for(int i=0;i<length/2;i++)
					{
						data[i]=in.readUnsignedShort();
					}
					OutPut = crypt(Integer.valueOf(pp.fileText1.getText()).intValue(),Integer.valueOf(pp.fileText4.getText()).intValue(),data);
					for(int i=0;i<length/2;i++)
					{
						out.writeShort((int)OutPut[i]);
					}
					out.flush();
					out.close();
					in.close();
					}catch(IOException IOE){}
					JOptionPane.showMessageDialog( c,"解密成功!"); 
			} 
		}); 
		 this.setVisible(true);
	}

	
/**
 * 对单个数字进行加密的函数
 * @param d
 * @param n
 * @param c
 * 返回加密后的数据
 */
	int RSAcrypt(int d,int n, int c)
	{
		int i;
		for(i=1;i<=d;i++)
		{
			if(Math.pow(c, i)>n)break;
		}
		int k = d/i;
		int x = d%i;
		double y  = (Math.pow(c, x))%n;
		Double z;
		while(k>0)
		{
			y = ((Math.pow(c, i))%n*y)%n;
			k--;
		}
		Double qq = new Double(y);
		return (short)qq.intValue();
	}
	
	/**
	 * 加密函数,或者解密函数
	 * 当输入私钥时进行加密,当输入公钥时进行解密
	 * 参数d,n分别为私钥的d,n或者公钥的e,n
	 * 加密或者解密的数据为data数组
	 */
	short[] crypt(int d,int n,int[] data)
	{
		int in;
		short ctr[] = new short[data.length];
		for(int i=0;i<data.length;i++)
		{
			ctr[i] = (short)RSAcrypt(d,n,data[i]);
		}
		return ctr;
	}
	
	
}

/**
 * 文件选择面板类,继承自JPanel 
 */
class FilePanel extends JPanel{ 
	FilePanel(String str){ 
	JLabel label = new JLabel(str); 
	JTextField fileText = new JTextField(35); 
	JButton chooseButton = new JButton("浏览..."); 
	this.add(label); 
	this.add(fileText); 
	this.add(chooseButton); 
	clickAction ca = new clickAction(this); 
	chooseButton.addActionListener(ca); 

	} 

	public String getFileName(){ 
	JTextField jtf = (JTextField)this.getComponent(1); 
	return jtf.getText(); 
	} 

	private class clickAction implements ActionListener{ 
	clickAction(Component c){ 
	cmpt = c; 
	} 

	public void actionPerformed(ActionEvent event){ 
	JFileChooser chooser = new JFileChooser(); 
	chooser.setCurrentDirectory(new File(".")); 
	int ret = chooser.showOpenDialog(cmpt); 
	if(ret==JFileChooser.APPROVE_OPTION){ 
	JPanel jp = (JPanel)cmpt; 
	JTextField jtf = (JTextField)jp.getComponent(1); 
	jtf.setText(chooser.getSelectedFile().getPath()); 
	} 
	} 

	private Component cmpt; 
	} 
	}


/**
 * 密钥获可视化类,继承自JPanel
 * 它显示由类key产生的随机公钥和私钥
 */
class keyPanel extends JPanel
{ 
	JTextField fileText1,fileText2,fileText3,fileText4;
	keyPanel(){ 
	JLabel label = new JLabel("公钥");
	label.setBorder(BorderFactory.createLineBorder(Color.blue));
	JLabel labe2 = new JLabel("e");
	JLabel labe3 = new JLabel("n");
	JLabel labe4 = new JLabel("私钥");
	labe4.setBorder(BorderFactory.createLineBorder(Color.blue));
	JLabel labe5 = new JLabel("d");
	JLabel labe6 = new JLabel("n"); 
	JButton b1 = new JButton("随机产生");
	fileText1 = new JTextField(7);
	fileText2 = new JTextField(7);
	fileText3 = new JTextField(7);
	fileText4 = new JTextField(7);
	this.add(label); 
	this.add(labe2); 
	this.add(fileText1);
	this.add(labe3); 
	this.add(fileText2);
	this.add(labe4); 
	this.add(labe5);
	this.add(fileText3);
	this.add(labe6); 
	this.add(fileText4);
	this.add(b1);
	b1.addActionListener(new ActionListener(){    //侦听函数
		public void actionPerformed(ActionEvent event)
		{ 
			key k = new key();
			fileText1.setText(String.valueOf(k.e));
			fileText2.setText(String.valueOf(k.n));
			fileText3.setText(String.valueOf(k.d));
			fileText4.setText(String.valueOf(k.n));
		} 
		}); 
	}
}



/**
 * 产生密钥对的类
 * p()产生一个随机素数
 * p,q分别为随机素数
 * n=p*q
 * e为小于(p-1)*(q-1)且与(p-1)*(q-1)互为素数的一个数
 * d为e关于(p-1)*(q-1)的乘法逆元
 * 公钥为e,n;私钥为d,n
 */
class key
{
	static int p;
	static int q;
	static int n;
	static int e;
	static int d;
	
	protected int howb(int M, int N) //求最大公约数
    {
        if(N<0||M<0)
        {
            return -1;
        }
        if(N==0)
        {
            return M;
        }
        return howb(N,M%N);
    }
	public static boolean isSushu(int x){//定义一个判断一个数是否是素数的函数
        if(x<2) return false;
        if( x==2)return true;
        for(int i=2;i<= Math.sqrt(x);i++)
            if(x%i==0) return false;
        return true;
    }
	protected int p()//产生随机素数
	{
		int p = new Random().nextInt(1024); //产生一个随机数
		while(!isSushu(p))p = new Random().nextInt(1024);
		return p;
	}
	key()
	{
		p =  p(); //产生大于3的素数1
		q =  p(); //产生大于3的素数2
		n = p*q;
		//while(n>131072 || n<=65536)n = p*q;
		e = (new Random().nextInt((p-1)*(q-1)))/3;//随机产生一个e值
		while(e<(p-1)*(q-1))
		{
			e++; //求e的值
			if(howb(e,(p-1)*(q-1))==1)break; //假如e与(p-1)*(q-1)互为素数,则结束循环
		}
		ExtendedEuclid ExtendedEuclid= new ExtendedEuclid();
		d = ExtendedEuclid.Extended((p-1)*(q-1),e);
	}
}


/*扩展欧几里德类
 * 即a1关于a的乘法逆元
 */
class ExtendedEuclid 
{
	int x1 = 1;
	int x2 = 0;
	int y1 = 0;
	int y2 = 1;
	int t1,t2,t3;
	int q;
	ExtendedEuclid(){}//构造函数为空
	public int Extended(int a,int a1)//求a1关于a的乘法逆元
	{
		int yy = a;
		while(a1 != 1)
		{
			q = a / a1 ;
			t1 = x1;
			t2 = x2;
			t3 = a;
			x1 = y1 ;
			x2 = y2 ;
			a = a1  ;
			y1 = t1 - q*x1;
			y2 = t2 - q*x2;
			a1 = t3 - q*a;
			if(a1 == 0) return -1;
		}
		if(y2%yy>=0)return y2%yy;
		else return yy+y2%yy;		
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -