鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 网站安全 > 加密解密 > >

MD5,RSA应用小程序

来源:互联网 作者:佚名 时间:2015-10-09 06:15
这学期写的最多的 应用 就是加密,文件处理,网络和多线程了。这个小 程序 是实验课做的,没多少技术含量,不过对于了解JAVA多线程,文件处理,加密,文件分割合并技术还是挺有参考价值的。 文件分割采用多线程,分割几块就开几个线程,所以PC上大文件有点慢

 这学期写的最多的应用就是加密,文件处理,网络和多线程了。这个小程序是实验课做的,没多少技术含量,不过对于了解JAVA多线程,文件处理,加密,文件分割合并技术还是挺有参考价值的。

   文件分割采用多线程,分割几块就开几个线程,所以PC上大文件有点慢,加密用的RSA(模式:公钥加密私钥解密),只进行文件头加密(整块加密它也做不了),校验用MD5(虽然已经被破解不过对了解数字指纹技术还是很经典的),对每个分块都进行校验以保证安全。说到文件分割合并技术,这可是分布式文件系统的一个基础架构。

看看效果吧:

 

1.没有图形界面,下面三个文件夹,加密切割或解密合并时得到的文件存放于GetFile中,将要进行切割的文件或要进行合并的分块文件放入LoadFile中,PrivateKey中放入密钥。

 

 

\

2.

将精舞门.avi放入LoadFile中,运行主程序FileCuter,输入切割份数6,完成加密分块

 

\

3.文件分块。

\

4.生成的密钥 

\

5.将分块文件导入LoadFile,输入指令2进行合并,合并时会进行密钥校验,分块校验和解密。合并后的文件名为RECOVER。

\

6.用diff命令对原文件和合并后的文件进行校验,文件没有差异,恢复成功!

\

7.将第四块拿掉,不完整被检测出来。

\

8.用别的密钥进行解密,被检测出来

\

8.载入正确的密钥,将分块3和5换为其他文件的分块(也就是分块被修改了),密钥审核通过,问题分块校验不通过。

\

9.修改问题文件的文件名也没用

\

10.文件相关信息被写入文件内部,表面文件名及文件顺序不影响程序的正确执行。

\

   实验目的主要是完成密码算法方面的应用程序在处理过小的文件时可能发生错误,但都不是主要问题~~

代码 : (VIM一个一个敲出来的,就不注释了)

CreateKey.java
import java.io.*;
public class CreateKey{
       private int id;
       public CreateKey(int id){
              this.id=id;
       }
       public  void Create(String filename,byte[] key,int num){
              RandomAccessFile fout=null;
              try{
                     fout=new RandomAccessFile("PrivateKey/"+filename+".pri_key","rw");
                     fout.seek(num*16);
                     fout.write(key);
                     fout.close();
              }catch(Exception e){
                     System.out.println("密钥写入失败!");
              }
       }
       public synchronized void writeMD5(int test,byte[] md5,String filename){
              while(id!=test){
                        try{
                                wait();
                        }catch(Exception e){
                                e.printStackTrace();
                        }
                }
              try{
                     RandomAccessFile fout=new RandomAccessFile("PrivateKey/"+filename+".pri_key","rw");
                     File f=new File("PrivateKey/"+filename+".pri_key");
                     fout.seek(16*(test-1));
                     fout.write(md5);
                     fout.close();
              }catch(Exception e){}
              id++;
              notifyAll();
       }                                
}
 Cut.java
 
import java.io.*;
import java.util.Map;
import java.security.*;
import org.apache.commons.codec.digest.DigestUtils;
public class Cut extends Thread{
       private int id;         
       private int num;
       private long start;  
       private long end;    
       private String file;
       private String filename;
       private byte[] key;
       private CreateKey ck;
       private BufferedInputStream fin;
       private BufferedOutputStream fout;
       private DigestInputStream dis;
       public Cut(int id,int num,long start,long end,String f,CreateKey ck){
              String[] name=f.split("\\.");
              this.file=f;
              this.start=start;
              this.end=end;
              this.filename=name[0];
              this.id=id;
              this.num=num;
              this.ck=ck;
       }
       public byte[] PriKey(){
              byte[] privatekey=new byte[400];;
              try{
                        Map<String,Object> keymap=RSACode.initKey();
                        this.key=RSACode.getPublicKeyEncoded(keymap);
                        privatekey=RSACode.getPrivateKeyEncoded(keymap);
                     ck.Create(filename,privatekey,num);
                     return privatekey;
                }catch(Exception e){
                }
              return privatekey;
        }
       public void Deal(){
              byte[] b=new byte[53];
              int i=0;
              int o=0;
              long prilen=end-start;
              try{
                     fin.skip(start);
                     fout.write(id);
                     fout.write(num);
                     if(id==1){
                            byte[] k=PriKey();
                            fout.write(MD5Code.getMD5(k));
                     }
              }catch(Exception e){}
              System.out.println(filename+id+".cut 创建中...");
              while(prilen>0){
                       try{      
                            if(prilen<53){
                                      byte[] b1=new byte[(int)prilen];
                                       i=dis.read(b1);
                                       fout.write(b1);
                                       fout.flush();
                                }
                               else{
                                    if(id==1&&o<1){
                                          i=fin.read(b);
                                            byte[] c=RSACode.encryptByPublicKey(b,key);
                                                 fout.write(c,0,c.length);
                                          fout.flush();
                                     }else{
                                          i=dis.read(b);
                                            fout.write(b,0,i);
                                            fout.flush();
                                      }
                            }
                               prilen-=i;
                            o++;
                        }catch(Exception e){}
              }
              try{
                     dis.close();
                     MessageDigest md=dis.getMessageDigest();
                       byte[] b1=md.digest();
                     System.out.println(filename+id+".cut 完成!");
                     ck.writeMD5(id,b1,filename);
                     fout.close();
              }catch(Exception e){}
       }
       public void run(){
              try{
                        fin=new BufferedInputStream(new FileInputStream("LoadFile/"+this.file));
                     dis=new DigestInputStream(fin,MessageDigest.getInstance("MD5"));
                }catch(Exception e){
                        System.out.println("读取文件失败!");
                }
              try{
                     fout=new BufferedOutputStream(new FileOutputStream("GetFile/"+filename+id+".cut"));
              }catch(Exception e){
                     System.out.println(filename+id+"创建失败!");
              }
              try{
                     Deal();
              }catch(Exception e){}
       }
}                         
FCut.java
 
import java.io.*;
public class FCut{
       private int num;
       private int stat=0;
       public FCut(int n){
              num=n;
       }
       public  void startCut(){
              CreateKey ck=new CreateKey(1);
              File dir=new File("LoadFile");
                File[] filelist;
                filelist=dir.listFiles();
              String filename=filelist[0].getName();
              long size=filelist[0].length();
              int o=1;
              long start=size/num;
              Cut[] cut=new Cut[num];
              for(int i=0;i<num;i++){
                     if(o==num)
                                cut[i]=new Cut(i+1,num,(i*start),size,filename,ck);
                        else
                                cut[i]=new Cut(i+1,num,(i*start),((i+1)*start),filename,ck);
                        cut[i].start();
              }
              for(int i=0;i<num;i++){
                        try{
                                cut[i].join();
                        }catch(Exception e){
                                e.printStackTrace();
                       }
              }
              stat=1;
       }
       public int getStat(){
              return stat;
       }
}
FileCuter.java
 
import java.util.Scanner;
public class FileCuter{
       public static void main(String[] star){
              Scanner sc=new Scanner(System.in);
              int cmd,num;
              System.out.println("\n           ****安全文件切割合并程序****\n");
              System.out.println("输入指令:1--文件加密切割,2--文件解密合并,3--退出\n");
              while(true){
                        System.out.print("CMD:>");
                        cmd=sc.nextInt();
                     if(cmd==1){
                            System.out.print("请输入切割份数:");
                            num=sc.nextInt();
                            FCut fc=new FCut(num);
                            fc.startCut();
                            while(true){
                                   if(fc.getStat()==1)break;
                            }
                     }
                     else if(cmd==2){
                            Merge m=new Merge();
                                m.Merge();
                     }
                     else if(cmd==3){
                            System.out.println("Bye!");
                            break;
                     }
                     else
                            System.out.println("输入不正确");
              }
       }
}
MD5Code.java
 
import org.bouncycastle.util.encoders.Base64;
import org.apache.commons.codec.digest.DigestUtils;
public class MD5Code{
       public static byte[] encodeMD5(String data)throws Exception{
              return DigestUtils.md5(data);
       }
       public static String decodeMD5(String data)throws Exception{
              return DigestUtils.md5Hex(data);
       }
       public static byte[] getMD5(byte[] data)throws Exception{
                return DigestUtils.md5(data);
        }
       public static String getMD5Hex(byte[] data)throws Exception{
              return DigestUtils.md5Hex(data);
       }
}
Merge.java
 
import java.io.*;
import java.util.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.binary.Hex;
public class Merge{
       public BufferedInputStream FinList(String s){
              BufferedInputStream fin=null;
                     try{
                            fin=new BufferedInputStream(new FileInputStream(s));
              }catch(Exception e){
                        e.printStackTrace();
                       }
              return fin;
       }
       public String[] FileList(){
              BufferedInputStream fin;
              File dir=new File("LoadFile");
              File[] flist=dir.listFiles();
              int len=flist.length;
              String[] name=new String[len];
              int[] id=new int[len];
              int test=0;
              for(int i=0;i<len;i++){
                     if(!flist[i].isDirectory()){
                            name[i]=flist[i].getName();
                                try{
                                        fin=FinList(flist[i].toString());
                                        id[i]=fin.read();
                                        test=fin.read();
                                   fin.close();
                                }catch(Exception e){
                                         e.printStackTrace();
                                 }
                        }
                     else
                            continue;
              }
              if(test!=len){
                     System.out.println("文件分块数目不正确!");
                     name[0]="0";
                     return name;
              }
              else{
                     for (int i=1;i<len;i++)
                                  for (int j=0;j<=len-i-1;j++)
                                  {
                                         if (id[j]>id[j+1])
                                         {
                                                  int t=id[j];
                                                  String temp=name[j];
                                                  id[j]=id[j+1];
                                                  name[j]=name[j+1];
                                                  id[j+1]=t;
                                                  name[j+1]=temp;
                                   }
                     }
                     return name;
              }
       }
       public String[] GetFileMD5(String[] flisttest){
              BufferedInputStream fin;
              String[] md5=new String[flisttest.length+1];
              File dir=new File("PrivateKey");
                File[] flist=dir.listFiles();
              if(flist.length==0){
                     System.out.println("密钥载入失败!");
                     md5[0]="0";
                     return md5;
              }
              byte[] b=new byte[16];
              try{
                     fin=FinList(flist[0].toString());
                     for(int i=0;i<flisttest.length;i++){
                            fin.read(b);
                            md5[i]=Hex.encodeHexString(b);
                     }
                     md5[flisttest.length]=DigestUtils.md5Hex(fin);
                     fin.close();
              }catch(Exception e){
                     System.out.println("密钥文件解析失败!");
              }
              return md5;
       }
       public int CheckFileMD5(String[] flist,String[] md5){
              int flag=1;
              BufferedInputStream fin;
              String m;
              for(int i=0;i<flist.length;i++){
                     try{
                            fin=FinList("LoadFile/"+flist[i]);
                            fin.read();
                            fin.read();
                            if(i==0){
                                   byte[] b=new byte[16];
                                   fin.read(b);
                                   if(!Hex.encodeHexString(b).equals(md5[md5.length-1])){
                                          System.out.println("密钥不正确!");
                                          flag=0;
                                   }
                                   else
                                          System.out.println("密钥验证通过!");
                                   fin.skip(64);
                                   m=DigestUtils.md5Hex(fin);
                            }
                            else{      
                                   m=DigestUtils.md5Hex(fin);
                            }
                            if(!md5[i].equals(m)){
                                   System.out.println("分块:"+flist[i]+" 校验失败!");
                                   flag=0;
                            }
                            else
                                   System.out.println("分块:"+flist[i]+" 验证通过!");
                            fin.close();
                     }catch(Exception e){
                            System.out.println("读取"+flist[i]+"MD5失败!");
                            flag=0;
                     }
              }
              return flag;
       }
       public byte[] GetKey(String[] fl){
              BufferedInputStream fin;
                File dir=new File("PrivateKey");
              File[] flist=dir.listFiles();
              File f=new File(flist[0].toString());
              int len=(int)(f.length()-fl.length*16);
                byte[] b=new byte[len];
                try{
                        fin=FinList(flist[0].toString());
                     fin.skip(fl.length*16);
                        fin.read(b);
                        fin.close();
                }catch(Exception e){
                        System.out.println("密钥文件解析失败!");
                }
                return b;
        }
       public void Merge(){
              String[] fl=FileList();
              if(fl[0].equals("0"))
                     return;
                String[] md5=GetFileMD5(fl);
              if(md5[0].equals("0"))
                     return;
                int a=CheckFileMD5(fl,md5);
              BufferedInputStream fin;
              if(a==0)
                     return;
              else{
                     try{
                            System.out.println("文件合并开始!");
                            BufferedOutputStream fout=new BufferedOutputStream(new FileOutputStream("GetFile/RECOVER"));
                            byte[] key=GetKey(fl);
                            byte[] b=new byte[64];
                            int n=0,sign=0;
                            for(int i=0;i<fl.length;i++){
                                   fin=FinList("LoadFile/"+fl[i]);
                                   fin.skip(2);
                                   System.out.println("分块: "+fl[i]+" 写入中...");
                                   if(i==0){
                                          fin.skip(16);
                                          while((n=fin.read(b))>0){
                                                 if(sign==0){
                                                        fout.write(RSACode.decryptByPrivateKey(b,key),0,53);
                                                        sign=1;
                                                 }
                                                 else
                                                        fout.write(b,0,n);  
                                          }
                                   }
                                   else{
                                          while((n=fin.read(b))>0){
                                                 fout.write(b,0,n);
                                          }
                                   }
                                   fin.close();
                            }
                            fout.close();
                     }catch(Exception e){
                            System.out.println("文件合并失败!");
                            return;
                     }
                     System.out.println("文件合并结束!");
              }
       }
}                  
 
RSACoder.java                           
 
 
import javax.crypto.Cipher;
public class RSACode{
       private static final String KEY_ALGORITHM="RSA";
       private static final String PUB_KEY="RSAPublicKey";
       private static final String PRI_KEY="RSAPrivateKey";
       private static final int KEY_SIZE=512;
       public static Map<String,Object> initKey()throws Exception{
              KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance(KEY_ALGORITHM);
              keyPairGen.initialize(KEY_SIZE);
              KeyPair keypair=keyPairGen.generateKeyPair();
              RSAPublicKey publickey=(RSAPublicKey)keypair.getPublic();
              RSAPrivateKey privatekey=(RSAPrivateKey)keypair.getPrivate();
              Map<String,Object> keymap=new HashMap<String,Object>(2);
              keymap.put(PUB_KEY,publickey);
              keymap.put(PRI_KEY,privatekey);
              return keymap;
       }
       public static byte[] getPublicKeyEncoded(Map<String,Object> map)throws Exception{
              Key key=(Key)map.get(PUB_KEY);
              return key.getEncoded();
       }
       public static byte[] getPrivateKeyEncoded(Map<String,Object> map)throws Exception{
              Key key=(Key)map.get(PRI_KEY);
              return key.getEncoded();
       }
       public static PublicKey PubKey(byte[] k)throws Exception{
              X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(k);
              KeyFactory keyfactory=KeyFactory.getInstance(KEY_ALGORITHM);
              PublicKey publickey=keyfactory.generatePublic(x509KeySpec);
              return publickey;
       }
       public static PrivateKey PriKey(byte[] k)throws Exception{
              PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(k);
              KeyFactory keyfactory=KeyFactory.getInstance(KEY_ALGORITHM);
              PrivateKey privatekey=keyfactory.generatePrivate(pkcs8KeySpec);
              return privatekey;
       }
       public static byte[] decryptByPublicKey(byte[] data,byte[] key)throws Exception{
              Cipher cipher=Cipher.getInstance(KEY_ALGORITHM);
              cipher.init(Cipher.DECRYPT_MODE,PubKey(key));
              return cipher.doFinal(data);
       }
       public static byte[] decryptByPrivateKey(byte[] data,byte[] key)throws Exception{
              Cipher cipher=Cipher.getInstance(KEY_ALGORITHM);
              cipher.init(Cipher.DECRYPT_MODE,PriKey(key));
              return cipher.doFinal(data);
       }
       public static byte[] encryptByPublicKey(byte[] data,byte[] key)throws Exception{
              Cipher cipher=Cipher.getInstance(KEY_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE,PubKey(key));
                return cipher.doFinal(data);
       }
       public static byte[] encryptByPrivateKey(byte[] data,byte[] key)throws Exception{
                Cipher cipher=Cipher.getInstance(KEY_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE,PriKey(key));
                return cipher.doFinal(data);
        }
}
 
             
 
本文出自 “ThinkingMyself” 博客

网友评论
<