




已阅读5页,还剩20页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘要XML 签名和 XML加密标准目前被广泛地用作构建快(building-block)技术。本文解释了 XML签名和 XML加密标准,并且说明了如何通过.NET 使用它们。注:本文的某些部分基于 .NET Framework 2.0 的预发布版本。与这些部分有关的所有信息都有可能更改。 XML签名和 XML加密标准目前被广泛地用作积木(building-block)技术。Microsoft Office InfoPath使用 XML签名对部分或整个表单进行签名。Web 服务使用 XML签名对SOAP消息进行签名,并且使用 XML加密技术对它们进行加密。基于 ClickOnce的应用程序的 XML清单(Visual Studio 2005 中的新增功能)也使用 XML签名。.NET Framework 1.x包含 XML签名标准的对象模型,而.NET Framework 2.0 则添加了其他支持,同时还添加了XML加密的对象模型。本文解释了 XML签名和 XML加密标准,并且说明了如何通过.NET 使用它们。有关实际的 XML签名规范,请参阅位于 /TR/xmldsig-core的W3C标准。数字签名在深入探讨 XML签名标准之前,让我们回顾一下数字签名的基础知识。因为防止恶意用户在传输期间改变消息很重要,所以数字签名保护数据的完整性,并且可以检测数据在到达接收地的途中受到的任何更改。因为能够标识发送方也很重要,所以消息通常使用发送方的私有(秘密)密钥进行签名,并且用相应的公钥进行验证,从而使接收者在知道发送方的公钥时可以确认发送方的标识。这可以防止恶意用户通过尝试作为已知的发送方发送消息,或者通过截获来自已知发送方的消息并将其替换为他们自己的消息(一种中间人形式的攻击),冒充已知的发送方。要创建数字签名,首先需要使用加密哈希函数来对需签名的消息进行哈希运算。对于任何长度的输入,加密哈希函数都会返回固定长度的位组,称为哈希值。该哈希值无法容易地重新转换为原来的输入。即使输入中只有一个位发生更改,哈希值也会以不可预知的方式更改,因此无法仅仅通过查找类似的哈希值来找到与原始输入类似的输入。一个常用的哈希函数是 SHA-1,它可以产生 160位的哈希值。下一个步骤是使用签名算法和您的私钥对该哈希值进行签名,以产生签名值。您用您的私钥创建该签名,以便具有您的公钥的其他人可以对其进行验证(本文稍后将对此进行详细讨论)。RSA 是一种流行的用于签名的加密算法。在您将消息和该签名发送给接收者之后,验证过程开始。收到的消息被在签名时使用的相同哈希函数用来进行哈希运算;然后,通过将签名值以及公钥和计算得到的哈希一起传递给签名算法,对签名值进行验证。如果计算得到的哈希与签名哈希相匹配,则签名有效。如果这两个哈希不匹配,则表明数据或签名已经更改,因此不能确保数据的完整性。还可以使用密钥哈希算法签名和验证数据,但是这超出了本文讨论的范围。.NET Framework已经为所有种类的哈希、加密/解密和签名/验证算法包含了一组丰富的类。有关这些类的详细信息,请参阅.NET Framework SDK 文档以及由 Brian LaMacchia等人编写的NET Framework Security (Addison-Wesley, 2002)。XML签名基础知识您可以使用 XML签名对任何种类的数据进行签名,这些数据包括 XML文档的某个部分、其他 XML文档或任何格式的其他数据。但是,实际上,XML 签名最常用于对以 XML表示的其他数据进行签名。XML 签名标准还非常灵活,它允许您在签名之前对数据进行筛选和转换,并且使您可以精确地选择要签名的内容以及签名方式。一个简单的文档:HelloWorld经过签名的文档:HelloWorldcbPT0951Ghb2G3UjpVjWw+7q0Bc=IoEwS(3 lines of Base64 text)XSo=图 1 签名前后的简单 XML文档让我们考察一个简单的 XML签名方案:对整个文档进行签名并且包含签名(参见图1)。请注意已经被添加到文档中的 Signature元素,该元素包含 XML签名。让我们看一下每个元素所包含的内容:SignedInfo该元素的子元素包含有关所签名的内容以及签名方式的所有信息。签名算法实际上应用于该元素及其所有子元素以生成签名。CanonicalizationMethod该元素指定了用于 SignedInfo元素以便将 XML规范化的规范化(C14N)算法。我们将在下文中讨论 C14N。SignatureMethod该元素指定了该签名的签名算法。在该示例中,签名算法是带有RSA(用于对产生的哈希值进行签名)的 SHA-1(用于哈希运算)。Reference这些元素指定了将要签名的数据以及在哈希运算之前应当如何对该数据进行处理。URI 属性(它表示统一资源标识符)标识要签名的数据,而 Transforms元素(稍后描述)指定在进行哈希运算之前如何处理数据。在该示例中,我们将使用特殊的URI空字符串,它指定包含签名的文档是要包含在签名中的数据。XML 签名标准对Reference数据使用间接签名机制。该标准不是对 Reference中的所有数据进行哈希运算然后加密哈希值,而是使用由 Reference的 DigestMethod元素所指定的算法对每个Reference的数据进行哈希运算,然后将哈希值存储到 Reference的 DigestValue元素中。接下来,对 SignedInfo元素和它的所有子元素(包括 Reference元素)进行哈希运算;哈希值被加密以生成签名。因此,您实际上是对 Reference元素中所引用数据的哈希的哈希进行签名,但是该方案仍然可以保护数据的完整性。图 2和图 3在匹配的 XML旁边显示了签名和验证过程。Transforms每个 Reference元素都可以具有零个或更多个为它指定的转换。这些转换按照它们在 XML中列出的顺序应用于该 Reference的数据。转换使您可以在对Reference的数据进行哈希运算之前对该数据进行筛选或修改。在该示例中,我们将使用包封式签名转换,该转换选择了包含文档中除 Signature元素以外的所有 XML。我们必须从将被签名的数据中移除 Signature元素,否则,当我们存储签名值时,可能会修改我们尝试签名的数据。我们将在下文中详细讨论转换。SignatureValue该元素包含通过签名 SignedInfo元素及其所有子元素而计算得到的签名值。图 2 签名过程现在,让我们讨论用于创建签名的处理模型(参见图 2)。首先,对于签名中的每个Reference元素: 按照转换在 Transforms元素下面出现的顺序,将 Transform元素中指定的每个转换算法应用于 Reference的数据。 使用 Reference的 DigestMethod元素所指定的哈希算法对经过转换的数据进行哈希运算。 在 Reference的 DigestValue元素中存储产生的哈希值。 下一个步骤是使用在签名的 CanonicalizationMethod元素中指定的算法规范化SignedInfo元素及其子元素。然后,使用在签名的 SignatureMethod元素中指定的算法对SignedInfo元素及其子元素进行签名。签名值被存储在 SignatureValue元素中。图 3 验证过程签名验证是刚刚描述的过程的逆过程(参见图 3)。首先,必须使用CanonicalizationMethod元素中指定的 C14N算法规范化 SignedInfo元素及其子元素。然后,必须针对 SignedInfo元素及其子元素验证 SignatureValue元素中存储的签名值。最后,对于签名中的每个 Reference元素: 按照转换在 Transforms元素下面出现的顺序,将 Reference的 Transform元素中指定的每个转换算法应用于 Reference的数据。 使用 Reference的 DigestMethod元素所指定的哈希算法对 Reference的经过转换的数据进行哈希运算。 将计算得到的哈希值与 DigestValue元素中存储的值进行比较。 如果签名验证成功,并且每个 Reference的哈希值与签名中存储的哈希值相等,则XML签名有效。否则,或者由 Reference元素之一引用的数据已经更改,或者 Signature元素已经更改。嵌入到由其签名的文档中的签名称为信封签名。用于创建这种签名的代码如图 4所示,用于验证该签名的代码如图 5所示。using System.Security.Cryptography;using System.Security.Cryptography.Xml;/ Also, add a reference to System.Security.dll/ Assume the data to sign is in the data.xml file, load it, and/ set up the signature object.XmlDocument doc = new XmlDocument();doc.Load(“data.xml“);SignedXml sig = new SignedXml(doc);/ Make a random RSA key, and set it on the signature for signing.RSA key = new RSACryptoServiceProvider();sig.SigningKey = key;/ Create a Reference to the containing document, add the enveloped/ transform, and then add the Reference to the signatureReference refr = new Reference(“);refr.AddTransform(new XmlDsigEnvelopedSignatureTransform();sig.AddReference(refr);/ Compute the signature, add it to the XML document, and savesig.ComputeSignature();doc.DocumentElement.AppendChild(sig.GetXml();doc.Save(“data-signed.xml“);图 4 创建一个信封签名using System.Security.Cryptography;using System.Security.Cryptography.Xml;/ Also, add a reference to System.Security.dll/ Load the signed dataXmlDocument doc = new XmlDocument();doc.PreserveWhitespace = true;doc.Load(“data-signed.xml“);/ Find the Signature element in the documentXmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable();nsm.AddNamespace(“dsig“, SignedXml.XmlDsigNamespaceUrl);XmlElement sigElt = (XmlElement)doc.SelectSingleNode(“/dsig:Signature“, nsm);/ Load the signature for verificationSignedXml sig = new SignedXml(doc);sig.LoadXml(sigElt);/ Verify the signature, assume the public key part of the/ signing key is in the key variableif (sig.CheckSignature(key)Console.WriteLine(“Signature verified“);else Console.WriteLine(“Signature not valid“);图 5 验证一个信封签名您已经了解了如何创建和验证包封式签名,它们很常用并且在对整个 XML文档进行签名时很方便,而且 XML签名标准还使您可以通过在 Reference元素中指定不同的 URI对其他数据进行签名。因此,让我们接下来考察一下不同类型的引用。引用除了包封式引用(其 URI属性为空字符串的 Reference元素)以外,在 XML签名标准中还定义了其他两个宽泛类型的引用:对分离数据的引用以及通过 ID对 XML数据进行的引用。分离数据位于包含签名的 XML文档的外部,这些引用可以指向另外一个 XML文档或任何其他类型的资源。当您在一个签名中对多个资源(例如,一个 XML文档以及由该文档引用的其他一些文件)进行签名时,通常会使用该类型的引用。下面的 XML代码片段显示了分离引用的一个示例:cbPT0951Ghb2G3UjpVjWw+7q0Bc=为了使用 Framework中的类来创建分离引用,只需在创建引用对象时将该引用的 URI设置为资源的 URI,然后 将该引用添加到签名中,如下所示:/ Create a Reference to detached data, assume a SignedXml object in sigReference refr = new Reference(“/UploadFiles_6597/200608/20060808155829128.jpg“);sig.AddReference(refr);通过 ID对 XML数据进行的引用指向包含签名的文档内部或签名本身内部的 XML。对于这些引用,签名引擎寻找其 ID属性与引用中的 URI匹配(不包括#)的元素。以下为一个基于 ID的引用的示例:cbPT0951Ghb2G3UjpVjWw+7q0Bc=如果 ID为“myData”的元素位于包含签名的文档中,则该引用是完整的,并且签名引擎将在处理该签名时找到它。您通常使用该类型的引用将签名的作用范围限制到示例文档的特定部分。例如,在文档处理应用程序中,审阅者通常只对他审阅的 XML文档部分(而不是整个文档)进行签名。该标准还允许您向 Object元素中的签名添加任意数据。Object元素的 XML看起来类似于以下代码行:Your XML goes here要创建基于 ID的引用(该引用指向包含签名的文档中已经存在的元素),请添加如下所示的代码:/ Create a Reference to XML data in the containing document,/ assume a SignedXml object in sigReference refr = new Reference(“#myData“);sig.AddReference(refr);如果基于 ID的引用指向了签名中的一个 Object元素,则除了添加该引用以外,还必须向签名中添加一个 DataObject,如刚才显示的代码中所示。数据对象可以包含您传入的任何 XML。/ Adds a DataObject with an Id of “#myData“ to the signature, assume a / SignedXml object in sig, and xml data of type XmlNodeList in dataDataObject dobj = new DataObject();dobj.Id = “myData“; / Note: no #dobj.Data = data; / XML Data of the Objectsig.AddObject(dobj);您通常使用指向 Object元素的引用来对有关签名的元数据进行签名,例如,签名者的唯一标识符或有关该签名的其他一些信息。转换转换通过允许您在生成引用的数据的哈希值之前修改该数据,使您可以对已签名的内容进行更多的控制。例如,信封式签名转换在对 XML文档进行签名之前会移除 Signature节点。引用可以指定任何数量的转换,这些转换按照在 Transforms元素中指定的顺序而做用。 .NET Framework中的类除了支持我们前面提到的信封式签名转换以外,还支持下列转换: 任何规范化算法都可以用作转换。 通过 Base64转换可以对 Base64编码数据进行解码。 通过 XSLT转换,可以在对 XML数据进行签名之前,向其应用 XSLT样式表。要应用的 XSLT样式表被指定为 Transform元素下的 XML。 通过 XPath转换可以用 XPath表达式筛选 XML数据。 XPath表达式被指定为 Transform元素下的 XPath元素的文本内容。需要注意的是,XPath转换充当筛选器,而不是充当在作为输入传递的 XML中选择节点的手段。该转换针对作为输入传递给该转换的每个节点计算 XPath表达式,结果被转换为布尔值。输入节点将被考虑以便传递计算,并且如果计算的结果为 true,则输入节点将被包含在转换的输出中。考虑转换的以下 XML输入:Some dataMore dataEven more data假设我们只希望选择“b”节点进行签名。带有 XPath表达式“ancestor-or-self:b”的 XPath转换将返回以下节点集(它正是我们所需要的):Some dataEven more data该 XPath表达式的 Transform元素看起来类似于下面的代码片段:ancestor-or-self:b要在签名时以编程方式创建转换,请创建某个转换对象的实例,适当设置它的属性,并且将其添加到它所应用于的引用。以下示例将上一个示例中使用的 XPath转换添加到某个引用中,以便创建转换:/ Add an XPath transform to a reference./ Assume a Reference object in refr XmlDocument doc = new XmlDocument();doc.LoadXml(“ancestor-or-self:b“);XmlDsigXPathTransform xptrans = new XmlDsigXPathTransform();xptrans.LoadInnerXml(doc.ChildNodes);refr.AddTransform(xptrans);规范化规范化的目的是为两个逻辑上相同但可能不是由相同的文本表示的 XML片段产生相同的 XML数据。例如,请观察下面两个代码片段。它们在逻辑上是相同的;它们的不同之处仅仅在于文本表示。但是如果您要对它们按原样进行哈希运算,则得到的哈希值将是不同的:Some textMore textSome textMore text要避免该问题,该标准中指定的默认规范化算法将执行很多任务,包括消除开始和结束标记中的空白以及将空元素转换为开始/结束标记对。但是,它不会更改元素内容中的任何空白。所执行操作的完整列表可以在 Canonical XML(位于 /TR/xml-c14n)中得到。签名引擎在必要时自动规范化数据,以便符合 W3C标准。特别地,每当签名引擎需要将 XML数据转换为二进制数据以便进行哈希运算时,都会规范化该数据。例如,当它准备对 SignedInfo元素及其子元素进行签名时,就会发生这种情况。当它准备引用或转换的输出以便进行签名时,也可能发生这种情况。例如,如果您使用基于 ID的引用(指向包含签名的文档中的其他 XML数据),并且该引用没有与其相关联的转换,则签名引擎在对该引用的 XML数据进行哈希运算之前将规范化该数据。密钥管理XML签名标准提供了 KeyInfo元素,帮助进行密钥管理。该元素可以存储密钥名称、密钥值、密钥检索方法或证书信息,以帮助接收方验证签名。该标准没有指定应当如何信任以及是否应当信任 KeyInfo元素中的任何信息。如果发送方和接收方共享一个受信任密钥列表,或者如果您发现了其他某种用于将密钥名称映射到密钥的方法,则 KeyInfo元素可能很有用。.NET Framework 1.x 具有一些对密钥名称、值和检索方法的支持,.NET Framework 2.0还包含对 X.509证书的支持。让我们假设发送方和接收方共享一个密钥列表,接收方对于他期望从其接收消息的每个发送方都具有一个公钥。签名应用程序可以添加以下代码,以便向签名中添加 KeyInfo元素:/ Adds an KeyInfo element with RSA public key information to the / signature. / Assumes a SignedXml object in sig, and an RSA object in key.KeyInfo ki = new KeyInfo();ki.AddClause(new RSAKeyValue(key);sig.KeyInfo = ki;该代码应当在调用 ComputeSignature之前添加。它将在签名中产生一个 KeyInfo元素,该元素看起来类似于以下代码:4LfG(2 lines of Base64 text)2Fr=AQAB这表示用来对 XML文档进行签名的 RSA公钥。接收方应用程序应当将该密钥与受信任密钥列表进行比较,如果该公钥不在列表中,则不应当信任文档。否则,攻击者就可以在传输过程中替换已经签名的文档,并且用另外一个密钥对其进行签名。如果签名包含与此类似的 RSAKeyValue,则验证代码可以调用 SignedXml类的 CheckSignature方法(它不采用任何参数),并且.NET Framework 将根据 RSAKeyValue元素计算出该密钥。下面是一个示例:/ Verify a signature that includes RSAKeyInfo or DSAKeyInfo./ Assume a SignedXml object in sig.bool verified = sig.CheckSignature();签名配置文件伴随 XML签名的灵活性而来的是一定数量的风险。因为转换是如此灵活,所以可能很难精确计算出签名涵盖了哪些数据,这可能导致意外的或不安全的结果。这些签名配置文件可以通过指定应用程序所支持的签名形式,在该方面提供帮助。尽管没有相应于签名配置文件的标准,但签名配置文件起码应当指定应用程序期望签名具有的引用和转换,以便您可以确保所期望签名的数据确实进行了签名。签名配置文件还可以包含其他数据,例如,期望签名数据具有的签名算法或密钥大小。应用程序应当检查并强制它所创建和验证的那些签名符合该应用程序所支持的签名配置文件。要更好地理解配置文件为什么如此重要,请考虑图 1。假设您要编写接受 XML签名数据的应用程序,但是您的应用程序只期望使用信封式签名转换而非任何其他转换的签名。现在,有人向您发送了带有额外 XPath转换的签名文档,如图 6所示。HelloWorldancestor-or-self:amN4R0653F4ethOiTBeAu+7q0Be=X4Ie(3 lines of Base64 text)nP3=图 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 transformpublic bool CheckSignatureProfile(XmlDocument doc)/ Make sure there is only one Signature elementXmlNamespaceManager 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 ReferenceXmlElement sigElt = (XmlElement)sigList0;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)refList0;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 transformXmlNodeList transList = refElt.SelectNodes(“dsig:Transforms/dsig:Transform“, nsm);if (transList.Count != 1)return false; /Wrong number of Transform elementsXmlElement transElt = (XmlElement)transList0;string transAlg = transElt.GetAttribute(“Algorithm“);if (transAlg != SignedXml.XmlDsigEnvelopedSignatureTransformUrl)return false; /Wrong type of transformreturn true;图 7 检验一个签名配置文件迄今为止,我们已经考察了 XML签名标准的一些不同方面以及 .NET Framework中对它的支持。让我们将这些功能中的某些功能一起放到一个更为完整的示例中。假设您要编写一个应用程序以便交换 XML形式的消息,并且您希望对该消息的全部内容进行签名。您还希望将一些有关签名者的 XML数据作为对象添加到 Signature元素中,以便只对该数据的signerID元素进行签名。您的应用程序可以访问一个众所周知的密钥列表,因此您还将在签名中存储公钥信息,并且检验以确保该密钥在验证期间映射到一个众所周知的密钥。用于签名和验证消息的代码包含在本文的完整代码下载中。用该代码对消息进行签名将产生如图 8所示的 XML签名。Some DataMore datacbPT0951Ghb2G3UjpVjWw+7q0Bc=ancestor-or-self:my:SignerIDmN4R0653F4ethOiTBeAu+7q0BeIoEwS.4LfG(2 lines of Base64 text)2Fr=AQABMike4815图 8 一个稍微复杂一些的签名文档.NET Framework 2.0中的新特性迄今为止讨论的所有 XML签名特性在.NET Framework 1.x 和 2.0中都可用。XML 加密和 X.509证书集成对于版本 2.0而言是新增特性。通过 X.509证书集成,可以更容易地将X.509证书用于 XML签名。通过新增的 X509CertificateEx类和相关的类,可以更容易地操纵和使用证书,并且 XML签名对象模型在适当的时候使用这些类。在本文的结尾,我们将对 X.509集成进行更详细的讨论。XML 加密是另外一个 W3C标准。正如 XML签名指定了有关创建 XML形式的数字签名的格式和处理模型一样,XML 加密对如何加密 XML形式的数据进行了标准化。XML 数字签名是通过 SignedXml类驱动的,而 XML加密是使用新的EncryptedXml类执行的。尽管 XML加密可以用来加密任意数据,但它最常用于加密其他XML。当以这种方式使用时,您将在文档的加密方式上拥有很多的灵活性。例如,可以用不同的密钥加密 XML文档的不同节点,同时将某些节点保留为明文。而且,由于用EncryptedXml类加密某些内容会产生 XML,因此您甚至可以加密已经加密的结果,该过程称为“超级加密”。让我们考察一下一些已经加密的 XML(参见图 9)。一件可以立刻注意到的有趣的事情是,XML 加密标准对某些元素(包括 KeyInfo元素)使用 XML签名命名空间。一个简单的文档:HelloWorld经过加密的文档:recipient_public_key PrI6(3 lines of Base64 text)Dwy4= awcH(3 lines of Base64 text)NNqQ= 图 9 加密前后的 XML文档EncryptedData元素EncryptedData是通过加密 XML生成的根元素,并且它包含有关数据的所有信息。EncryptedData包含三个主要的子元素:EncryptionMethod 指定用来加密数据的算法;KeyInfo元素提供有关使用哪个密钥来解密数据的信息;CipherData 或 CipherReference元素则包含实际的加密信息。EncryptionMethod 元素指定用来加密和解密密码数据的算法,这些算法由 URI指定,就像 XML签名标准一样。EncryptionMethod 同时用于加密数据和加密密钥,但并非每个算法都可以同时用于这两个场合。图 10显示了每个算法可以用在哪个场合。请注意,高级加密标准(Advanced Encryption Standard,AES)还可用于 192位和128位密码;您只需在 URI中更改密钥大小。EncryptedXml类的 URI属性 加密数据 加密密钥 XmlEncAES256Url AESXmlEncAES256KeyWrapUrl DES XmlEncDESUrl XmlEncTripleDESUrl TripleDESXmlEncTripleDESKeyWrapUrl RSA XmlEncRSA1_5Url 图 10 使用加密算法的场合在加密或解密任何数据之前,加密引擎需要知道应当使用哪个密钥来加密和解密。可以用两种方式标识密钥,最容易的方式是为该密钥分配一个名称,并且在 KeyInfo元素内部放置一个 KeyName元素。解密文档的应用程序可以获得 KeyName标记,并提供与给定的名称相匹配的密钥。该应用程序不仅提供密钥的名称,还可以将密钥作为 EncryptedKey直接嵌入到 KeyInfo元素中。EncryptedKey 与 EncryptedData包含相同的元素:加密方法、用来解密该密钥的密钥以及构成加密密钥的密码数据。加密密钥通常与命名密钥结合使用,以作为随机会话密钥。首先,生成一个随机会话密钥并使用它来加密 XML;然后,用需要解密文档的众所周知的命名密钥加密会话密钥本身;最后,将该命名密钥插入到加密会话密钥的 KeyInfo元素中,并且将该加密会话密钥附加到加密数据中。图 9中的示例说明了这一点。XML 数据的加密方法是 256位的 AES,而 AES算法的密钥也已经被加密。EncryptedKey元素包含有关如何加密 AES算法的密钥的信息,在该示例中,它是使用名为recipients_public_key的 RSA密钥加密的。使用 XML加密的应用程序必须将该名称映射到实际的密钥。可以将实际的加密数据嵌入到 EncryptedData元素中,或者将其放到单独的位置,然后从 EncryptedData中引用它。如果要将密码数据直接放到 EncryptedData中,则会将其作为 Base64编码的二进制文件放到 CipherData元素中。图 9中的示例使用了一个CipherData元素。另一个方案是将加密数据放到 EncryptedData元素外部。可以将密码文本放在从该文档中的另一个元素到远程 Web站点的任何位置。在这两种情况下,都将使用CipherReference元素而不是 CipherData元素(参见图 11)。CipherReference的位置 URI格式 密码文本格式 相同文档中 #order Base64字符串远程 Web站点 /order.bin 二进制图 11 CipherReferences对远程 Web站点的 CipherReferences提出了一个有趣的安全方案。在解密 XML的过程中,解密引擎必须转到任意 Web站点并下载密码文本。由于要解密的文档可能不会受到与完成解密的代码同等程度的信任,因此应当在沙箱中完成该操作。这是通过向EncryptedXml对象提供它将在解析任何 CipherReferences时使用的证据来完成的。通过沙箱可以更安全地执行代码,因为解密应用程序可能不具有与提供加密数据的站点相同的权限。例如,如果应用程序试图解密不受信任的站点,并且该不受信任的站点不能够访问位于安全的、受信任站点上的某些受信任的数据,则它可以通过包含密码引用,让解密应用程序为它访问该文件。由于.NET 安全策略是以证据为中心的,因此所提供的证据通常应当至少包含 Site、Zone 和 Url对象,如下所示:/ Create evidence based on the referring documentEvidence evidence = new Evidence();evidence.AddHost(new Zone(SecurityZone.Internet);evidence.AddHost(new Site(“untrustedsite“);evidence.AddHost(new Url(“untrustedsite/encrypted.xml“);EncryptedXml exml = new EncryptedXml(untrustedDoc, evidence);XML加密示例现在,让我们考察一下如何使用 .NET Framework 2.0中的类。该示例说明了一个销售CD的 Web站点,每次购买活动都被归档到一个 XML文档中,其中包含有关订购了哪些商品、发货信息和信用卡号的详细信息。图 12显示了订单的一些示例 XML。Def Leppard: PyromaniaOzzy Osbourne: Goodbye to RomanceShawn FarkasOne Microsoft Way980520000-0000-0000-0000图 12 一个 CD订单的 XML在该实例中,公司内部的任何人查看订单中的项目是一件可以接受的事情,但是您可能希望对某些更为敏感的数据(例如,发货地址和信用卡信息)进行保密。实际上,您甚至可能希望对它们分别进行加密,以便只有计帐部门能够访问信用卡信息,并且只有发货部门能够访问发货地址。要做到这一点,需要对付款元素下的 XML部分进行加密,以便只有计帐部门能够访问它,只有发货部门可以获得的单独密钥将用来加密发货元素。最后,整个订单将用公司中任何人都可以获得的密钥加密。第一步是创建一个 EncryptedXml对象。这是通过传入具有要加密或解密的数据的文档完成的,如下所示:/ Assumes the order is in the order.xml file.XmlDocument doc = new XmlDocument();doc.Load(“order.xml“);EncryptedXml exml = new EncryptedXml(doc);在加密 XML之前,必须将要使用的密钥映射到它们的相应名称,这些名称将出现在KeyName元素中。可以使用 EncryptedXml的 AddKeyMapping方法完成该任务:/ Set up the key mapping. Assumes a method called GetBillingKey/ that returns the RSA key for the billing department.RSA billingKey = GetBillingKey();exml.AddKeyNameMapping(“billing“, billingKey);在设置了密钥-名称映射以后,加密 XML就很容易了。第一步是调用 Encrypt方法,它完成实际的加密,并且返回一个 EncryptedData对象以表示文档的加密部分。之后,您需要调用一个工具方法,将原始 XML文档的未加密部分换为新的加密数据:/ Find the element to encrypt.XmlElement paymentElement = doc.SelectSingleNode(“/order/payment“) as XmlElement;/ Encrypt the payment element, passing in the key name.EncryptedData encryptedPayment = exml.Encrypt(paymentElement, “billing“);/ Swap the encrypted element for the unencrypted element.EncryptedXml.ReplaceElement(paymentElement, encryptedPayment, true);这将产生图 13中所示的加密 XML。Def Leppard: Pyromania Ozzy Osbourne: Goodbye to Romance Shawn Farkas One Microsoft Way 98052 billingSce6lLD+u2f8HzPFyuGxTF32z4mb2ugql3JuJIPAqIP98iYs+Muhqg=FXKC(3 lines of Base64 text)ApqQt图 13 加密了支付信息的 CD订单请观察一下加密数据,您可以看到我们已经描述的各个部分。首先,EncryptionMethod元素显示了 AES-256的 URI,这意味着该文档用带有 256位密钥的 AES算法(由 RijndaelManaged类实现)加密。Encrypt 方法为您生成一个随机的会话密钥;该密钥在 KeyInfo元素中加密。通过观察 EncryptedKey元素,您可以看到它是用 RSA算法并借助于一个名为“billing”的密钥加密的。CipherData 元素存放了该密钥的加密值。在 KeyInfo的后面是包含加密内容(原来的付款元素)的 CipherData。解密刚才说明的文档很容易,这要归功于 EncryptedXml的 DecryptDocument方法。首先,加载含有加密内容的文档:/ Assumes the encrypted order is in encrypted.xmlXmlDocument doc = new XmlDocument(“encrypted.xml“);EncryptedXml exml = new EncryptedXml(doc, documentEvidence);接下来,设置密钥-名称映射,如下所示:/ Set up the key mapping. Assumes a method called GetBillingKey/ that returns the RSA key for the billing department.RSA billingKey = GetBillingKey();exml.AddKeyNameMapping(“billing“, billingKey);最后,调用 DecryptDocument。该方法将负责解密密码文本,并且将加密的 XML替换为它的解密内容。/ Decrypt the encrypted XML in the documentexml.DecryptDocument();在幕后,加密引擎将在调用 DecryptDocument时寻找任何 EncryptedData元素,在这种情况下,它只找到付款元素下面的那个元素。在找到该元素以后,它将查看 KeyInfo子句并且看到它持有加密的 256位 AES密钥。加密密钥的 KeyInfo将显示它是用名为billing的 RSA密钥加密的。然后,它检查密钥映射表以寻找名为 billing的密钥。我们为一个名为 billing的密钥添加了一个密钥映射,因此引擎随后将解密加密密钥。既然引擎具有密钥
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 药品物品设备管理制度
- 药品销售人员管理制度
- 药店仓库盘存管理制度
- 药店店员薪酬管理制度
- 药店营业区域管理制度
- 薪资待遇具体管理制度
- 设备包机责任管理制度
- 设备巡回检查管理制度
- 设备日常养护管理制度
- 设备现场图文管理制度
- 30题投资管理类岗位常见面试问题含HR问题考察点及参考回答
- 校园网络运维服务需求
- 2023调度自动化系统主站信息自动联调技术规范
- 物流公司运输安全管理制度
- 三个合伙人分配合同范本
- PLC课程设计-四人抢答器
- 资产管理+数据资产确权登记导则(2022年)
- SL637-2023年《水力机械辅助设备系统安装工程施工质量验收评定标准》
- 油雾润滑操作规程及要求
- 浆料回收工艺及流程
- “四电”工程施工工艺标准
评论
0/150
提交评论