C语言中的MD5实现用于XML文件

时间:2010-01-28 14:00:34

标签: c xml md5 checksum

我需要实现MD5校验和来验证XML文件中的MD5校验和,包括所有XML标记以及从我们的客户端收到的XML标记。接收到的MD5校验和的长度为32字节十六进制数字。

我们需要在校验和计算之前将MD5 Checksum字段设置为接收到的XML文件中的0,我们必须在收到的XML文件中独立计算和验证MD5校验和值。

我们的应用程序在C中实现。请协助我如何实现它。

由于

5 个答案:

答案 0 :(得分:4)

这直接取决于用于XML解析的库。然而,这很棘手,因为在将校验和嵌入到内部后,您无法将MD5嵌入XML文件中,除非您仅从特定元素执行校验和。据我所知,你独立收到MD5?它是从整个文件计算出来的,还是仅从标签/内容计算出来的?

确切的解决方案取决于使用的代码。

根据您的评论,您需要执行以下步骤:

  • 加载xml文件(可能甚至是纯文本)阅读MD5
  • 将文件中的MD5替换为零,将文件写下(或更好地写入内存)
  • 在纯文件数据上运行MD5,并将其与
  • 之前存储的值进行比较

答案 1 :(得分:1)

您应该使用MD5的公共域实现,而不是编写自己的。我听说Colin Plumb的版本被广泛使用。

答案 2 :(得分:1)

不要重新发明轮子,使用经过验证的现有解决方案:http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html

顺便说一下,这是我googled "md5 c implementation"时出现的第一个链接。

答案 3 :(得分:0)

这是相当讨厌的。建议的方法似乎暗示您需要将XML文档解析为类似DOM树的内容,找到MD5校验和并将其存储以供将来参考。然后在重新序列化文档并计算MD5哈希值之前,将校验和替换为0。这一切听起来都可行,但可能很棘手。我看到的主要困难是您的文档的新序列化可能与原始序列不同,并且与XML不相关(例如在属性值周围使用单引号或双引号,添加换行符或甚至不同的编码)导致哈希值不同。如果你走这条路线,你需要确保你的应用程序和用于创建文档的程序首先做出相同的选择。对于这类问题,规范XML是标准解决方案(http://www.w3.org/TR/xml-c14n)。

但是,我会做一些与众不同的事情。运气好的话,编写一个正则表达式来定位文件中的MD5哈希并将其替换为0.应该很容易。然后可以使用它来获取哈希值,并在重新计算哈希值之前将其替换为XML文件中的0。这解决了解析,更改和重新序列化XML文档的所有可能问题。为了说明我将假设散列'33d4046bea07e89134aecfcaf7e73015'存在于XML文件中,如下所示:

<docRoot xmlns='some-irrelevant-uri>
  <myData>Blar blar</myData>
  <myExtraData number='1'/>
  <docHash MD5='33d4046bea07e89134aecfcaf7e73015' />
  <evenMoreOfMyData number='34'/>
</docRoot>

(我称之为hash.xml),MD5应该被32个零替换(所以散列是正确的),并使用perl,md5和bash说明shell命令行上的过程。 (希望将此转换为C并不会因为存在正则表达式和散列库而太难。)

分解问题,首先需要能够找到文件中的哈希值:

perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml 

(这是通过查找docHash元素的MD5属性的开始,允许可能的其他属性,然后抓取接下来的32个十六进制字符。如果它找到它们,它会在魔法$ _变量中将它们打包,如果不是将$ _设置为空,然后为每一行打印$ _的值。这样就会打印出字符串“33d4046bea07e89134aecfcaf7e73015”。)

然后你需要计算已用零替换的文件的哈希值:

perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5

(其中正则表达式几乎相同,但这次将十六进制字符替换为零并打印整个文件。然后通过md5散列程序将结果通过管道计算MD5。将它们放在一起有点bash给出:

if [ `perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml` = `perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5` ] ; then echo OK; else echo ERROR; fi
执行这两个小命令的

,比较输出并在输出匹配时打印“OK”,如果不匹配则打印“ERROR”。显然这只是一个简单的原型,并且使用了错误的语言,我认为它说明了最直接的解决方案。

顺便提一下,为什么要将哈希放在XML文档中?据我所知,与在旁边通道上传递哈希相比,它没有任何优势(甚至可以像第二个名为documentname.md5的文件一样简单),并且使哈希验证更加困难。

答案 4 :(得分:0)

查看这些示例,了解如何将XMLDSIG标准与.net

一起使用

您应该考虑更改保留空格的设置。