效验文件的完整性

在文本文件的传输过程中,如:A将文件file,传给了B,但在传输的过程中,文件可能被C截获,并且C对文件file进行更改后变成file_alias,C再将file_alias传给B,这样B实际接受的是文件file_alias,而不是文件file

 

解决方案

使用消息认证码(message authentication code,MAC)函数的密码秘钥加密策略,能够实现数据完整性和数据源的认证,另外这样作还可以以非常小的代价加密整个明文。MAC的基本思想是:对于每个需要通过网络进行传输的消息m,利用数学函数h计算出结果h(m),然后将结果赋给消息m本身。如果在消息的传输过程中出现了错误,比如所接受的消息a不同于发送的原始消息m。则消息接收者能够检测到异常:通过独立的计算h(a),并将计算结构与h(m)进行比较。如果结果不一致,则意味发生了异常。

与只使用纯粹的,简单的散列函数产生的消息摘要相比,MAC函数将秘密密钥加密与散列摘要函数结合起来,产生了一个值,只有拥有秘密密要的实体才能验证该值。用这种方法,MAC函数解决了数据完整性和数据源的认证。

 

示例程序:

import java.io.*;

 

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

 

public class Jmac2 {

       public Mac mac;

      

       public Jmac2()throws Exception{

              mac = Mac.getInstance("HmacMD5");

              byte[] keybt="zhangjuwei".getBytes();

              SecretKey key = new SecretKeySpec(keybt, "DESede");

              mac.init(key);

       }

      

       //添加mac到文件

    public void addMac(File file) throws Exception{

           InputStreamReader  read = new InputStreamReader (new FileInputStream(file),"UTF-8");

           BufferedReader reader=new BufferedReader(read);

           String line;

           StringBuffer sb=new StringBuffer();

           while ((line = reader.readLine()) != null) {

                  sb.append(line);

           }

           System.out.println(sb.toString());

           byte[] filebt=sb.toString().getBytes();

           System.out.println("1 "+filebt.toString());

           byte[] macCode = mac.doFinal(filebt);

           System.out.println("2 "+new String(macCode,"UTF-8"));

           System.out.println("3 "+macCode.length);

           String macString=toHexString(macCode);

           System.out.println("4 "+macString);

           System.out.println("5 "+macString.length());

           read.close();

           //mac追加写入文件

           FileOutputStream fos=new FileOutputStream(file,true);

           fos.write(macString.getBytes());

           fos.close();

          

    }

   

    //读取带有mac的文件,并验证文件的完整性

    public void checkMac(File file)throws Exception{

           InputStreamReader  read = new InputStreamReader (new FileInputStream(file),"UTF-8");

           BufferedReader reader=new BufferedReader(read);

           String line;

           StringBuffer sb=new StringBuffer();

           while ((line = reader.readLine()) != null) {

                  sb.append(line);

           }

           int len=sb.length();

        System.out.println("0 "+sb.toString());

           String oldMacStr=sb.substring(len-32,len);

           System.out.println("1 "+oldMacStr +" len="+oldMacStr.length());

           String fileStr=sb.substring(0,len-32);

           byte[] macCode = mac.doFinal(fileStr.getBytes());

           System.out.println("2 "+new String(macCode,"UTF-8"));

           System.out.println("3 "+macCode.length);

           String newMacStr=toHexString(macCode);

           System.out.println("4 "+newMacStr);

           if(oldMacStr.equals(newMacStr)){

                  System.out.println("成功!");

           }else{

                  System.out.println("失败!");

           }

          

    }

    public static void main(String[] args)throws Exception{

           Jmac2 mac2=new Jmac2();

           //mac2.addMac(new File("D:/workspace/for_JSecurty.txt"));

           mac2.checkMac(new File("D:/workspace/for_JSecurty.txt"));

    }

   

    //mac转变格式16进制

    public static String toHexString ( byte[] b ){

           StringBuffer sb = new StringBuffer( b.length * 2 );

           for ( int i=0; i<b.length; i++ ){

                  //look up high nibble char

                  sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] );

                  //look up low nibble char

                  sb.append( hexChar [b[i] & 0x0f] );

           }

           return sb.toString();

       }

    static char[] hexChar = {

           '0' , '1' , '2' , '3' ,

           '4' , '5' , '6' , '7' ,

           '8' , '9' , 'a' , 'b' ,

           'c' , 'd' , 'e' , 'f'};

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值