伴随XML签名的灵活性而来的是一定数量的风险。因为转换是如此灵活,所以可能很难精确计算出签名涵盖了哪些数据,这可能导致意外的或不安全的结果。这些签名配置文件可以通过指定应用程序所支持的签名形式,在该方面提供帮助。尽管没有相应于签名配置文件的标准,但签名配置文件起码应当指定应用程序期望签名具有的引用和转换,以便您可以确保所期望签名的数据确实进行了签名。签名配置文件还可以包含其他数据,例如,期望签名数据具有的签名算法或密钥大小。应用程序应当检查并强制它所创建和验证的那些签名符合该应用程序所支持的签名配置文件。要更好地理解配置文件为什么如此重要,请考虑图1。假设您要编写接受XML签名数据的应用程序,但是您的应用程序只期望使用信封式签名转换而非任何其他转换的签名。现在,有人向您发送了带有额外XPath转换的签名文档,如图6所示。
Hello
World
signature"/>
>
图6 使用额外的转换对文档进行签名
在图6的示例中,签名只涵盖示例文档中的“a”元素。如果您刚刚加载了该文档并且调用了SignedXml类的CheckSignature方法,则即使“b”元素未被该签名涵盖,该签名仍然可能验证,这是因为签名引擎将应用在该签名中指定的转换。如果应用程序依赖于该签名涵盖了“b”元素这一前提,则数据的完整性已经遭到损害。应用程序应当检验只有一个引用具有作为URI的空字符串并且该引用具有一个转换——信封式签名,从而验证它所期望的签名配置文件。它会在验证签名时拒绝任何其他签名配置文件。一些用于检验该签名配置文件的示例代码显示在图7中。
// This method checks the signature profile for the signature
// in the supplied document. It ensures there is only one
// Signature element and only one enveloped reference with only
// one enveloped signature transform
public bool CheckSignatureProfile(XmlDocument doc)
{
// Make sure there is only one Signature element
XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl);
XmlNodeList sigList = doc.SelectNodes("//dsig:Signature", nsm);
if (sigList.Count > 1)
return false; //Wrong number of Signature elements
//Make sure the Signature element has only one Reference
XmlElement sigElt = (XmlElement)sigList[0];
XmlNodeList refList = sigElt.SelectNodes(
"dsig:SignedInfo/dsig:Reference", nsm);
if (refList.Count > 1)
return false; //Wrong number of Reference elements
// Make sure the Reference URI is ""
XmlElement refElt = (XmlElement)refList[0];
XmlAttributeCollection refAttrs = refElt.Attributes;
XmlNode uriAttr = refAttrs.GetNamedItem("URI");
if ((uriAttr == null) || (uriAttr.Value != ""))
return false; // Wrong type of reference
// Make sure the only tranform is the enveloped signature transform
XmlNodeList transList = refElt.SelectNodes(
"dsig:Transforms/dsig:Transform", nsm);
if (transList.Count != 1)
return false; //Wrong number of Transform elements
XmlElement transElt = (XmlElement)transList[0];
string transAlg = transElt.GetAttribute("Algorithm");
if (transAlg != SignedXml.XmlDsigEnvelopedSignatureTransformUrl)
return false; //Wrong type of transform
return true;
}
图7 检验一个签名配置文件

