繁体   English   中英

XML文件在C中的MD5实现

[英]MD5 implementation in C for a XML file

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

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

我们的应用程序是用C实现的。请协助我实现该方法。

谢谢

这直接取决于用于XML解析的库。 但是,这很棘手,因为您无法将MD5嵌入XML文件本身,因为在将校验和嵌入内部之后,除非仅对特定元素进行校验和。 据我了解,您是独立接收MD5的吗? 它是根据整个文件还是仅根据标签/内容计算的?

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

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

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

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

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

顺便说一句,这是我在Google搜索“ md5 c实现”时出现的第一个链接。

真讨厌 建议的方法似乎暗示您需要将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个零(因此哈希是正确的),并在shell命令行上使用perl,md5和bash演示了该过程。 (鉴于存在正则表达式和哈希库,希望将其转换为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的第二个文件中那样简单的东西),也使哈希验证更加困难。

查看这些示例,了解如何在.net中使用XMLDSIG标准。

您也许应该考虑更改保留空白的设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM