赞
踩
最近和小伙伴一起构建了一个包含仿射、流密码RC4、流密码LFSR+JK,DES及RSA的加解密系统。界面包括加解密算法选择框,加密解密按钮,加密明文信息框以及解密密文信息框。
完整代码已经上传到github上了,里面的README.md有具体的操作说明教程,需要的同学可以自取,地址:https://github.com/Alexlingl/Cryptology
下面就大致介绍一下这个加解密系统的构建过程。
一、界面的设计与实现:
(一)、界面的设计:
(二)、界面的实现
1、布局:采用边框布局BorderLayout。它会将界面分为东南西北中四个部分,相应的,我们在北部添加一个Jpanel,作为按钮等组件的容器。在东部添加一个JPanel,作为JScrollPane的容器,呈现待处理的具体信息。在中部添加一个JPanel,也是作为JScrollPane的容器,不同的是它呈现的是处理后的具体信息。
2、信息框:使用JScrollPane可以实现信息过多时,可以下拉的效果,但是如果我们要在上面展示文字,还需要往上面添加一个JTextArea组件。
3、打开文件功能:调用JFileChoose来实现,点击后会出现一个从计算机中选择文件的界面。
4、算法下拉可选框:调用了JComboBox
5、最终的界面实现
二、界面监控与后台:
(一)、“选择文件”功能的按钮监控与后台逻辑实现:
1、首先我们需要给按钮添加监听机制
2、接着,我们需要保存获取的文件
3、最后利用addmessageleft这个方法,把选择的文件内容展示在待处理的信息框中
(二)、可选框的监听与后台逻辑实现:
1、首先需要给可选框添加监听机制
2、其次我们需要记录可选框中用户当前所选择的内容,这里我定义了一个choosetype来作为标志。根据用户不同的选择来给这个变量赋值。
(三)、加解密按钮的监听与后台逻辑实现:
1、首先还是需要给两个按钮添加监听机制
2、接着我们需要判断用户点击的是“加密”还是“解密”按钮,并进行不同的处理
3、最后,我们需要根据用户当前下拉框中选择的算法来进行相应的处理
以仿射加密为例来看一下具体的处理过程
首先定义一个临时存储数据的动态字符串数组tmp,并调用事先定义好的仿射对象的加密方法encrypt()对文本中的信息一行行地进行加密,加密结果就存放在tmp中。接着我们把tmp传给MessageWindows对象mw中的processed_text属性,这个就是处理后的信息。调用WriteStringToFile()方法把加密后的信息输出到“C:\\Users\\Administrator\\Documents\\仿射密文.txt”这个文件中。最后再调用addmessageright把处理后的信息显示到右边的信息显示框即可。
三、代码:
界面类
- package player3;
-
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStreamWriter;
- import java.util.ArrayList;
-
- import javax.swing.BorderFactory;
- import javax.swing.JButton;
- import javax.swing.JComboBox;
- import javax.swing.JFrame;
- import javax.swing.JPanel;
- import javax.swing.JScrollPane;
- import javax.swing.JTextArea;
-
-
- public class MessageWindows extends JFrame implements Config{
-
- public static ArrayList<String>messageList;
- // 三块面板,一块是背景,两块是信息显示界面
- public JPanel jPanel1,jPanelback2,jPanelback3;
- //两块信息显示界面,分别添加在JPanelback1和JPanelback2上面。直接加载JPanel上会出现大小无法调节等问题
- public JScrollPane jPanel2,jPanel3;
- //文件菜单按钮
- public JButton mnFile;
- // 两个按钮,一个是加密,一个是解密
- public JButton jButton1, jButton2;
- //输出台
- public JTextArea jTextAreainput,jTextAreaoutput;
- //选择进行加密的类型
- public int choosetype;
- //待处理的文本
- public static ArrayList<String> text = new ArrayList();
- //待处理的文本
- public static ArrayList<String> processed_text = new ArrayList();
-
-
- public MessageWindows() {
- initComp();
- this.choosetype=0;
- messageList=new ArrayList();
- }
-
- public void initComp() {
-
- this.setTitle("系统消息界面");
- //设置顶级容器的大小,setSize()只对顶级容器有效
- this.setSize(MainWindows_WIDTH,MainWindows_HIGHTH);
- //窗体关闭时结束程序
- this.setDefaultCloseOperation(3);
- //设置窗体居中
- this.setLocationRelativeTo(null);
- this.setResizable(false);
-
- jPanel1= new JPanel();
- jPanelback2=new JPanel();
- jPanelback3=new JPanel();
-
- //下拉可选框
- String[] choose={"仿射","流密码RC4","流密码LFSRJK","DES","RSA"};
- JComboBox box=new JComboBox(choose);
- //三个按钮
- mnFile= new JButton("选择文件");
- jButton1= new JButton("加密");
- jButton2= new JButton("解密");
-
- //设置为边界布局
- this.setLayout(new BorderLayout());
-
- box.setPreferredSize(new Dimension(Button_WIDTH, Button_HIGHTH));
- mnFile.setPreferredSize(new Dimension(Button_WIDTH, Button_HIGHTH));
- jButton1.setPreferredSize(new Dimension(Button_WIDTH, Button_HIGHTH));
- jButton2.setPreferredSize(new Dimension(Button_WIDTH, Button_HIGHTH));
-
- //在画板面板添加组件
- jPanel1.add(mnFile);
- jPanel1.add(box);
- jPanel1.add(jButton1);
- jPanel1.add(jButton2);
- jPanel1.setPreferredSize(new Dimension(NorthPanel_WIDTH,NorthPanel_HIGHTH));
- jPanelback2.setPreferredSize(new Dimension(WestPanel_WIDTH,WestPanel_HIGHTH));
- jPanelback3.setPreferredSize(new Dimension(EastPanel_WIDTH,EastPanel_HIGHTH));
-
- //待处理的信息,将选择的待处理文本显示到界面上
- jTextAreainput=new JTextArea();
- jPanel2= new JScrollPane(jTextAreainput);
- jPanel2.setBackground(Color.LIGHT_GRAY);
- jPanel2.setBounds(41,34, WestPanel_WIDTH, 194);
- jPanel2.setBorder(BorderFactory.createTitledBorder("待处理的信息"));
- jPanel2.setPreferredSize(new Dimension(WestPanel_WIDTH,WestPanel_HIGHTH));
-
- //处理后的信息,将处理后的文本信息显示到界面上
- jTextAreaoutput=new JTextArea();
- jPanel3= new JScrollPane(jTextAreaoutput);
- jPanel3.setBackground(Color.LIGHT_GRAY);
- jPanel3.setBounds(41,34, EastPanel_WIDTH, 194);
- jPanel3.setBorder(BorderFactory.createTitledBorder("加/解密后的信息"));
- jPanel3.setPreferredSize(new Dimension(EastPanel_WIDTH,EastPanel_HIGHTH));
-
- jPanelback2.add(jPanel2);
- jPanelback3.add(jPanel3);
-
- //将界面加到布局上
- this.add(jPanel1,BorderLayout.NORTH);
- this.add(jPanelback2,BorderLayout.WEST);
- this.add(jPanelback3,BorderLayout.EAST);
-
- this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- //设置界面可见
- this.setVisible(true);
-
- //为文件选择按钮添加监听机制
- mnFile.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e) {
- try {
- PlayerMain.openVideo();
- } catch (IOException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- });
-
- //为可选框添加监听机制
- box.addActionListener(new ButtonListener(this,box));
- //为按钮1,2添加监听机制
- jButton1.addActionListener(new ButtonListener(this));
- jButton2.addActionListener(new ButtonListener(this));
- }
-
- //将处理信息加到左边界面的方法
- public void addmessageleft(ArrayList<String> text) throws FileNotFoundException{
- this.text = text;
- jTextAreainput.append("当前进行加/解密的文本\n");
- jTextAreainput.paintImmediately(jTextAreainput.getBounds());
- for(int i=0;i<text.size();i++){
- jTextAreainput.append(text.get(i)+"\n");
- jTextAreainput.paintImmediately(jTextAreainput.getBounds());
- }
- }
-
- //将处理后的信息加到右边界面上
- public void addmessageright(ArrayList<String> processed_text) throws FileNotFoundException{
- this.processed_text = processed_text;
- jTextAreaoutput.append("当前加/解密后得到的文本\n");
- jTextAreaoutput.paintImmediately(jTextAreainput.getBounds());
- for(int i=0;i<processed_text.size();i++){
- jTextAreaoutput.append(processed_text.get(i)+"\n");
- jTextAreaoutput.paintImmediately(jTextAreaoutput.getBounds());
- }
- }
-
- //把处理后信息输入到文本文件中
- public void WriteStringToFile(ArrayList<String> processed_text,String filepath) throws IOException {
- OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filepath),"UTF-8");
- for(int i=0;i<processed_text.size();i++){
- osw.append(processed_text.get(i)+"\n");
- }
- osw.close();
- }
- }
界面监听类:
- package player3;
-
- //设置按钮监听方法ButttonLitener类
- import java.awt.event.ActionListener;
- import java.awt.event.ActionEvent;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import javax.swing.JComboBox;
- import des.DESUtil;
- import jklfsr.Jk;
- import fangshe.Fangshe;
- import rc4.Stream_cipher;
- import rsa.RSA;
-
- //实现对JPanel的监听接口处理
- public class ButtonListener implements ActionListener{
- public JComboBox box;
- public MessageWindows mw;
- public Fangshe fs=new Fangshe();
- public RSA rsa=new RSA();
- public Stream_cipher rc4=new Stream_cipher();
- public Jk jk=new Jk();
- public DESUtil des=new DESUtil();
-
- //构造方法一,只需要传界面对象
- public ButtonListener(MessageWindows mw){
- this.mw=mw;
- }
- //构造方法二,需要传界面对象和下拉可选框的对象
- public ButtonListener(MessageWindows mw,JComboBox box){
- this.mw=mw;
- this.box=box;
- }
-
- //在console中展示当前文本
- public void showtext(ArrayList<String>text){
- for(int i=0;i<text.size();i++){
- System.out.println(text.get(i));
- }
- }
-
- //当界面发生操作时进行处理
- public void actionPerformed(ActionEvent e) {
- //根据点击的按钮做出相应的处理
- if(e.getActionCommand().equals("加密")) {
- //选择进行仿射加密
- if(mw.choosetype==0){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(fs.encrypt(mw.text.get(i)));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- //将加密结果输出到文件
- mw.WriteStringToFile(mw.processed_text, "C:\\Users\\Administrator\\Documents\\仿射密文.txt");
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择流密码RC4进行加密
- else if(mw.choosetype==1){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(PlayerMain.toBinary(rc4.RC4_encrypt(mw.text.get(i))));
- }
- showtext(tmp);
- try {
- mw.WriteStringToFile(tmp, "C:\\Users\\Administrator\\Documents\\RC4密文.txt");
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择流密码LFSRJK进行加密
- else if(mw.choosetype==2){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(PlayerMain.toBinary(jk.JK_encrypt(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.WriteStringToFile(tmp, "C:\\Users\\Administrator\\Documents\\LFSRJK密文.txt");
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择DES进行加密
- else if(mw.choosetype==3){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(PlayerMain.convertByteToHexString(des.jdkDECENcode(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.WriteStringToFile(mw.processed_text, "C:\\Users\\Administrator\\Documents\\DES密文.txt");
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择进行RSA加密
- else if(mw.choosetype==4){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(PlayerMain.toBinary(rsa.encryption(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.WriteStringToFile(tmp, "C:\\Users\\Administrator\\Documents\\RSA密文.txt");
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- }
- //判断当前点击的按钮是不是解密
- else if(e.getActionCommand().equals("解密")) {
- if(mw.choosetype==0){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(fs.deciphering(mw.text.get(i)));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择RC4进行解密
- else if(mw.choosetype==1){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- System.out.println(mw.text.get(i));
- tmp.add(rc4.RC4_encrypt(PlayerMain.BinstrToStr(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
-
- }
- //选择流密码LFSRJK进行解密
- else if(mw.choosetype==2){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(jk.JK_encrypt(PlayerMain.BinstrToStr(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择DES进行解密
- else if(mw.choosetype==3){
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- System.out.println(mw.text.get(i));
- byte[] bytetmp=PlayerMain.convertHexStringToByte(mw.text.get(i));
- tmp.add(new String(des.jdkDECDecode(bytetmp)));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- //选择RSA进行解密
- else if(mw.choosetype==4){
- //选择进行RSA解密
- ArrayList<String>tmp=new ArrayList();
- for(int i=0;i<mw.text.size();i++){
- tmp.add(rsa.decrypt(PlayerMain.BinstrToStr(mw.text.get(i))));
- }
- showtext(tmp);
- mw.processed_text=tmp;
- try {
- mw.addmessageright(mw.processed_text);
- } catch (FileNotFoundException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
-
- }
- //"仿射","流密码RC4","流密码LFSRJK","DES","RSA"
- else if(box.getSelectedItem().equals("仿射")) {
- mw.choosetype=0;
- }
- else if(box.getSelectedItem().equals("流密码RC4")){
- mw.choosetype=1;
- }
- else if(box.getSelectedItem().equals("流密码LFSRJK")){
- mw.choosetype=2;
- }
- else if(box.getSelectedItem().equals("DES")) {
- mw.choosetype=3;
- }
- else if(box.getSelectedItem().equals("RSA")){
- mw.choosetype=4;
- }
-
- }
-
- }
选择文件类:
- package player3;
-
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Scanner;
-
- import javax.swing.JFileChooser;
-
-
- public class PlayerMain {
- //界面类
- static MessageWindows frame;
- //待加解密的字符串
- public static ArrayList<String> text = new ArrayList();
- //处理后的字符串
- public static ArrayList<String> processed_text = new ArrayList();
-
- //程序的主函数入口,相当于c++的main函数
- public static void main(String[] args) {
- //创建主程序界面运行窗体
- frame=new MessageWindows();
- frame.setVisible(true);
- }
-
- //byte数组转十六进制字符串
- public static String convertByteToHexString(byte[] bytes) {
- String result = "";
- for(int i=0;i<bytes.length; i++) {
- int temp = bytes[i]&0xff;
- String tempHex = Integer.toHexString(temp);
- if(tempHex.length()<2) {
- result +="0"+tempHex;
- }
- else {
- result += tempHex;
- }
- }
- return result;
- }
-
- //将字符串转为二进制流
- public static String toBinary(String str){
- char[] strChar=str.toCharArray();
- String result="";
- for(int i=0;i<strChar.length;i++){
- result +=Integer.toBinaryString(strChar[i])+ " ";
- }
- return result;
- }
-
- private static int[] BinstrToIntArray(String binStr) {
- char[] temp=binStr.toCharArray();
- int[] result=new int[temp.length];
- for(int i=0;i<temp.length;i++) {
- result[i]=temp[i]-48;
- }
- return result;
- }
-
- //将二进制转换成字符
- private static char BinstrToChar(String binStr){
- int[] temp=BinstrToIntArray(binStr);
- int sum=0;
- for(int i=0; i<temp.length;i++){
- sum +=temp[temp.length-1-i]<<i;
- }
- return (char)sum;
- }
- public static String BinstrToStr(String binStr){
- String[] tempStr=binStr.split(" ");
- char[] tempChar=new char[tempStr.length];
- for(int i=0;i<tempStr.length;i++) {
- tempChar[i]=BinstrToChar(tempStr[i]);
- }
- return String.valueOf(tempChar);
- }
-
- //十六进制字符串转为byte数组
- public static byte[] convertHexStringToByte(String str) {
- System.out.println(str);
- if(str == null || str.trim().equals("")) {
- return new byte[0];
- }
-
- byte[] bytes = new byte[str.length() / 2];
- for(int i = 0; i < str.length() / 2; i++) {
- String subStr = str.substring(i * 2, i * 2 + 2);
- bytes[i] = (byte) Integer.parseInt(subStr, 16);
- }
-
- return bytes;
- }
-
- //打开文件
- public static void openVideo() throws IOException {
- JFileChooser chooser=new JFileChooser();
- int v=chooser.showOpenDialog(null);
- if(v==JFileChooser.APPROVE_OPTION){
- File file=chooser.getSelectedFile();
- ArrayList<String> tmp = new ArrayList();
- Scanner sc = new Scanner(file);
- while(sc.hasNextLine()){
- tmp.add(sc.nextLine());
- }
- System.out.println("tmp="+tmp);
- text = tmp;
- //把选择的文件传过去
- frame.addmessageleft(text);
- }
- }
- }
-
四、注意事项
(一)、编码问题:不同加密方式产生的字符各不相同,DES等加密算法加密后生成的字符无论是utf-8还是GBK异或是unicode都没办法很好地表示出来。如果直接把DES加密后字符串写到文本中,会出现乱码的问题。于是最终我决定把加密后的信息都转为二进制字符串进行保存,等待需要解密时再转为字符串进行处理。
(二)、JScrollPane必须放在JPanel上面,如果直接放在JFrame的布局上,会出现无法调节JScrollPane大小的问题。
(三)、外部包的导入与生成
外部包的生成:右击要生成外部包的包,选择Export->JAR file
外部包的导入
先把外部包粘贴到lib中
右击要导入的包,选择build path即可。导入成功后我们是可以在Referenced Libraries中看到相应的包的
这篇博客只讲了整个系统的架构实现,具体的算法实现涉及的内容太多,这里就不展开讲了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。