XML 关系转换算法

XML Relationship Transform Algorithm

我正在尝试验证带有数字签名的 MS Word *.docx 文件。为了进行验证,我必须计算引用节点的摘要并检查它是否与签名中给出的摘要相同 (sig1.xml)。我找不到有关如何实现关系转换以计算该摘要的信息。

签名部分XML(sig1.xml)如下:

<Object Id="idPackageObject" xmlns:mdssi="http://schemas.openxmlformats.org/package/2006/digital-signature">
<Manifest><Reference URI="/_rels/.rels?ContentType=application/vnd.openxmlformats-package.relationships+xml">
<Transforms><Transform Algorithm="http://schemas.openxmlformats.org/package/2006/RelationshipTransform">    
<mdssi:RelationshipReference SourceId="rId1"/></Transform>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>1vWU/YTF/7t6ZjnE44gAFTbZvvA=</DigestValue>....(next ref node ....)..
<Reference URI="/word/document.xml?ContentType=application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>s2yQEJrQSfC0YoRe1hvm+IGBpJQ=</DigestValue></Reference>.....More Reference Nodes.....

/_rels/.rels文件自己:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin" Target="_xmlsignatures/origin.sigs"/>
</Relationships>

所以我需要计算 /_rels/.rels 的 SHA1,但在计算之前我必须应用关系变换和 C14N。

当我计算没有关系转换的节点摘要时(例如:这个节点的:)

<Reference URI="/word/document.xml?ContentType=application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"> 
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>s2yQEJrQSfC0YoRe1hvm+IGBpJQ=</DigestValue>
</Reference> 

一切都很好,只需对引用的 URI 进行 SHA1(/word/document.xml 在这种情况下)给我与给定签名节点的散列相同的散列。但是当涉及到具有关系转换的节点时 - 计算永远不会给出与签名中所述相同的值。

我的一般问题是在哪里可以找到有关此关系转换的信息以及如何实现它?

谢谢,

格奥尔基

在这种情况下,关于转换和关系转换的主要信息来源可以在 ECMA 的“Office Open XML 文件格式 - Open Packaging Conventions”中找到纸。 Link here.

重要的部分是13.2.4.24。

Relationship Transform 应创建 .rels 文件的副本,在本例中为“/_rels/.rels”并删除所有 Relationship 与 [= 不匹配的节点28=]SourceId。该文件最终会被散列并创建摘要。

The package implementer shall remove all Relationship elements that do not have either an Id value that matches any SourceId value or a Type value that matches any SourceType value, among the SourceId and SourceType values specified in the transform definition.

在第 3 步中,"Prepare for canonicalization" 它还指出:

The package implementer shall add a TargetMode attribute with its default value, if this optional attribute is missing from the Relationship element

因为我们在同一包中的文件之间创建关系,所以我们的值为“Internal”。您需要在对其进行哈希处理之前添加此属性。

所以在转换和 c14n 之后,你应该有:

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Target="word/document.xml" TargetMode="Internal" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"></Relationship></Relationships>

注意:如果您使用的是 unix 系统,请注意换行符,OPC 使用 CRLF 而不是 LF。