数字签名及 Checksum 校验和

本贴最后更新于 2650 天前,其中的信息可能已经水流花落

数字签名及验签

一般情况,为了证明文件或信件从源端通过网络传输到目的端未被人为篡改,通常采用数字签名的技术。
通过如下简单几步实现数据签名及验签。

发送方数字签名过程:

  1. 发送者通过散列函数将带发送的数据加工成散列值;
  2. 发送者用私钥对散列值进行加密生成一段数字签名;
  3. 发送者将待发送数据、数字签名、存有公钥的证书一并发送给接受者。

接受方验签过程:

  1. 提取出接收到的明文数据,用散列函数加工成散列值;
  2. 用从信任签名者证书中提取的公钥,将数字签名字串解密成散列值;
  3. 将第一步和第二部中的散列值进行比对,若比对一致则验签成功,反之信息被篡改。
    下图是数字签名及验签处理流程图:
    Image of Digital Signature

Checksum 校验和

除了数字签名之外,有没有一种简单的用于在相对安全的环境下,校验传送文件完整性的方法呢?
不需要证书也不需要解密,可以简单通过 Checksum 校验和实现。
以下说明来自维基百科:

校验和(英语:Checksum)是冗余校验的一种形式。 它是通过错误检测方法,对经过空间(如通信)或者时间(如计算机存储)传送的数据的完整性进行检查的一种简单方法。
计算机领域常见的校验和的方法有循环冗余校验(CRC)、MD5、SHA 家族等。
产生校验和的实际过程一般是向校验函数或校验和算法输入给定的数据,一个良好的校验和算法通常会对进行很小的修改的输入数据都会输出一个显著不同的值。

一般现在比较常用的是 SHA 家族校验。

linux 下的 Checksum 命令

通常发行版的 Linux 版本都自带了 Checksum 的命令工具,不同发行版命令可能不同。大部分 linux 版本都包含了 sha1sum 命令工具。
使用非常简单如下:

$sha1sum {filename} 该命令会输出Checksum的散列值及文件名

windows 下的 Checksum 命令

windows 默认是没有自带 Checksum 命令工具的,如果要实现类似 linux 里的 sha1sum 命令结果该怎么办?
微软还是很厚的地,免费提供了插件供大家下载使用,这个插件名字叫 The File Checksum Integrity Verifier (FCIV),就是一个 fciv.exe 文件。
下面是下载地址:
link to fciv.exe download page!

windows 下 java 编程将文件 Checksum 值写入 EOJ 文件

实际就是在 java 程序里调用 fciv.exe 命令,计算出文件的散列值,再将其追加到 EOJ 文件末尾。使用了 apache common 包里的 exec 类库。
以下是简单示例代码:

import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.PumpStreamHandler; /** * * The checksum class implements below functions: * read the EOJ file for each record * call the fciv.exe command capture the checksum value * and write into the EOJ file * * @author lee * */ public class CheckSumClass { /** * @param args */ public static void main(String[] args) { //EOJ file full name including the file path String eojFile = args[0]; //fciv.exe file path String cksumFile = args[1]; //flat file path String flatfilePath = args[2]; if(null==eojFile||null==cksumFile||null==flatfilePath ||"".equals(eojFile)||"".equals(cksumFile) ||"".equals(flatfilePath)){ System.err.println("The error parameters!"); System.exit(-1); } FileInputStream fi = null; PrintWriter pw = null; File file = null; Scanner in = null; List<String> cksumList = new ArrayList<String>(); try{ fi = new FileInputStream(eojFile); file = new File(eojFile); in = new Scanner(fi); String currentLine = null; while(in.hasNextLine()){ currentLine = in.nextLine(); if(currentLine!=null&&!"".equals(currentLine.trim())){ String[] tokens = currentLine.split("~"); String fileName = tokens[0]; //execute fciv.exe command and capture result value put into the cksumList ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); String command = cksumFile+" -wp -sha1 "+flatfilePath+"\\"+fileName; CommandLine commandline = CommandLine.parse(command); DefaultExecutor exec = new DefaultExecutor(); PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream); exec.setStreamHandler(streamHandler); exec.execute(commandline); String output = outputStream.toString(); String outstrs[] = output.split("\r\n"); String shavalue = outstrs[3].split(" ")[0]; cksumList.add(currentLine+"~"+shavalue); } } //write the checksum value into EOJ file pw = new PrintWriter(file); for(int j=0;j<cksumList.size();j++){ pw.println(cksumList.get(j)); } pw.flush(); }catch(Exception ex){ ex.printStackTrace(); }finally{ if(fi!=null) try { fi.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(pw!=null) pw.close(); if(in!=null) in.close(); if(file!=null) file = null; } } }

转载请保留文章链接:https://jblog.com.cn!
谢谢合作!

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...