深蓝居

关注MS的VS2008和SQL Server 2008

常用链接

统计

积分与排名

朋友

学习生活

最新评论

用C#实现pdf文件的完整性验证

        现在对文件的完整性验证,防止文件被篡改的技术已经比较成熟,一般使用数字签名,数字水印等,最近我在一个项目中也遇到了防篡改的需求。该项目要求用户将原始发票用专门的扫描程序扫描成pdf文件,然后将该pdf文件传到服务器上,在上传的同时必须要验证这个pdf是没有被手工修改过的。我刚一接触到这个需求想到的就是使用数字水印,要不然就直接使用PDF的数字签名功能,不过这些方法都感觉比较比较复杂,一大堆的英文文档也没有心思去研究,于是琢磨了半天,写了一个简化版的数字水印程序,实现了pdf文件完整性验证。
        验证的基本思路是:
            对文件全部内容计算其MD5值,这样无论用户修改了文件的任何一个地方,那么生成的MD5的是完全不一样的,我们可以将这个MD5写到文件的一个隐藏区,一般二进制文件格式都有文件头和文件体部分,而文件头是用户看不到的,一般也会预留一部分字节用于以后扩展,或可以在文件头写入特殊标记的数据。于是研究了一下pdf文件的格式,试着往其第10个字节插入了MD5值,结果文件虽然可以使用,但是每次打开的时候都会提示“文件修复”。原来是写在头上面的内容将pdf文件的字节数和文件中对象的地址改变了,导致了文件错误,原因找到了那么解决办法也就有了,为了不改变pdf文件中对象的地址,那么我们将这个md5写在文件尾不就可以了嘛!于是在客户端(扫描程序)将扫描出的pdf文件流计算MD5值,然后将该文件流和MD5值一起写到硬盘上,形成一个添加了MD5值的pdf文件。文件可以正常打开和使用,而且用户也不会看到我们添加的这个MD5值。
            在服务器端,我们将上传上来的文件流除了最后32个字节以为的部分计算MD5值(这儿取32个字节是因为最后这32字节是我们写的MD5),将前面部分算出的MD5和最后32个字节的MD5进行比较,如果一样那么说明这个文件从扫描程序生成以后没有被人为篡改过,否则说明该文件要么不是用我们这个扫描程序生成的要么就是被篡改了。这样验证通过以后我们才将该文件流写到服务器硬盘上。
相关程序代码

以上代码不仅仅只适用于PDF文件,对于其他一些格式也可以用,这主要是取决于文件的格式规范。关于PDF,官方有相关文档,不过大家觉得麻烦可以看看这篇文章:http://blog.csdn.net/pdfMaker/archive/2006/01/09/573990.aspx
【出自博客园深蓝居,转载请注明作者出处】

posted on 2007-03-30 16:18 深蓝 阅读(2746) 评论(20)  编辑 收藏 所属分类: .Net开发

评论

#1楼  2007-03-30 16:38 Jeffers Yuan      

当文件比较大时,性能如何?   回复  引用  查看    

#2楼  2007-03-30 16:50 iCaca      

文件大的时候查md5很慢...   回复  引用  查看    

#3楼  2007-03-30 16:57 雨玲珑      

应该在加一个key ,就是用户的密钥。一起运算

否则人家随便写个工具,就可以搞定   回复  引用  查看    

#4楼 [楼主] 2007-03-30 16:59 深蓝      

一般大文件的文件完整性也是通过MD5来校验的,当然以上的代码就不行了,不可能一次就把大文件读取到byte[]中,不过可以小小修改一下,每读一段(比如256K)就算一次MD5,最后把所有的MD5串起来再对串起来的字符串算一个MD5.   回复  引用  查看    

#5楼 [楼主] 2007-03-30 17:00 深蓝      

Re:雨玲珑 我在代码中是加了Key的,将算出的MD5和Key串起来再MD5了一次。   回复  引用  查看    

#6楼  2007-03-30 17:43 火狐 [未注册用户]

有价值呀,程序很好   回复  引用    

#7楼  2007-03-30 17:52 Clark Zheng      

@深蓝
雨玲珑是指在为每个人生成一个公钥和私钥吧   回复  引用  查看    

#8楼  2007-03-30 22:38 Leepy      

有价值,先收藏了!   回复  引用  查看    

#9楼  2007-03-31 00:05 wyn [未注册用户]

问楼主一下问题!

今天我知道了你的算法,

我在上传PDF文件时,更改了内容,差按你的算法MD5,得出值后写在后面32位
你怎么办?

  回复  引用    

#10楼  2007-03-31 00:08 wyn [未注册用户]

显然这是不行的!做数字签名不是用MD5,你看一下关于DSA或RSA吧


  回复  引用    

#11楼  2007-03-31 00:21 volnet(可以叫我大V)      

MD5的计算确实很需要关注性能的问题。
  回复  引用  查看    

#12楼  2007-03-31 00:33 i.Posei      

文件校验 v1.0
http://www.cnblogs.com/ipqn/archive/2006/10/24/538780.html

hehe   回复  引用  查看    

#13楼 [楼主] 2007-03-31 00:44 深蓝      

回wyn:你就算是知道了我是这个算法,但是你必须还要知道我这儿用的key是多少你才可以修改pdf文件而且校验通过。
还有,我这个方法的确不是真正的数字签名,只是一种防篡改的简单实现方法。   回复  引用  查看    

#14楼  2007-03-31 08:39 茄子 [未注册用户]

先收起来,
以后有需要在慢慢研究   回复  引用    

#15楼  2007-03-31 08:50 weiweibtm [未注册用户]

不错收藏一下有空在研究先谢谢了   回复  引用    

#16楼  2007-03-31 09:16 e表      

先收藏!! (纯.net写的web报表设计工具: http://ebiao.cnblogs.com/ )   回复  引用  查看    

#17楼  2007-04-02 08:18 popo [未注册用户]

pdf文件本身没有安全机制吗   回复  引用    

#18楼  2007-04-05 16:16 ricardo [未注册用户]

想请教一下楼主 我用delphi来实现 发现生成的pdf文件不可用

不知道为什么   回复  引用    

#19楼  2007-07-25 18:18 est      

好久没看前辈的文章啦,呵呵

http://initiative.yo2.cn/   回复  引用  查看    

#20楼  2007-08-21 22:07 reaper [未注册用户]

cool....   回复  引用    


我要啦免费统计