XML签名(XML Signature)的基本结构和作用是什么?
程序猿
•
2025年12月17日 03:20:32
•
好文分享 •
阅读 0
xml签名 通过在xml文档中添加“数字指纹”来确保其完整性和来源可靠性。1. 其核心是元素,包含(含、、等子元素)、和;2. 支持三种签名模式:enveloped signature(签名嵌入文档内部)、enveloping signature(签名包裹内容)、detached signature(签名与内容分离);3. 可使用java的javax.xml.crypto、python 的xmlsec、c#的system.security.cryptography.xml等库实现签名生成与验证;4. 广泛应用于电子发票、电子病历、金融交易、软件更新和web services安全等场景,确保数据不可篡改和身份可信。选择强哈希算法(如sha256)和足够密钥长度并定期更新密钥是保障安全的关键措施。
… … … Hello, world!
XML签名有哪些不同的签名模式?
XML签名支持多种签名模式,主要区别 在于
元素在XML文档中的位置:
Enveloped Signature (信封签名) :
元素是XML文档的根元素,它“包裹”着被签名的内容。上面的例子就是Enveloped Signature。
Enveloping Signature (内含签名) :
元素包含被签名的内容。 也就是说,
元素本身是根元素,并且它内部包含了要签名的XML片段。
Detached Signature (分离签名) :
元素和被签名的内容是分离的。
元素通过
属性指向外部的XML文档。
选择哪种签名模式取决于具体的需求。Enveloped Signature 适合签名整个XML文档,而 Detached Signature 适合签名外部资源。
如何使用编程语言生成和验证XML签名?
许多编程语言都提供了XML签名库,可以简化签名和验证过程。
Java : Java的内置库
提供了XML签名API。你可以使用它来创建、验证XML签名。 Apache Santuario – XML Security for Java 也是一个流行的选择,提供了更丰富的功能和更好的性能。
// 使用 Java XML Digital Signature API 签名 XML 文档import javax.xml.crypto.*;import javax.xml.crypto.dsig.*;import javax.xml.crypto.dsig.dom.DOMSignContext;import javax.xml.crypto.dsig.keyinfo.*;import javax.xml.crypto.dsig.spec.*;import java.io.*;import java.security.*;import java.security.cert.Certificate;import java.util.*;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;public class XMLSigner { public static void main(String[] args) throws Exception { // 1. 加载 XML 文档 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Document doc = dbf.newDocumentBuilder().parse(new File("document.xml")); // 2. 创建密钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // 3. 创建 XMLSignatureFactory XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); // 4. 创建 Reference 对象 Reference ref = fac.newReference ("", fac.newDigestMethod(DigestMethod.SHA256, null), Collections.singletonList (fac.newTransform (Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); // 5. 创建 SignedInfo 对象 SignedInfo signedInfo = fac.newSignedInfo (fac.newCanonicalizationMethod (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (C14NMethodParameterSpec) null), fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref)); // 6. 创建 KeyInfo 对象 KeyInfoFactory kif = fac.getKeyInfoFactory(); List x509Content = new ArrayList(); x509Content.add(publicKey); KeyInfo keyInfo = kif.newKeyInfo(Collections.singletonList(kif.newKeyValue(publicKey))); // 7. 创建 Signature 对象 XMLSignature signature = fac.newXMLSignature(signedInfo, keyInfo); // 8. 创建 DOMSignContext 并签名 DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement()); signature.sign(dsc); // 9. 输出签名后的 XML 文档 TransformerFactory tf = TransformerFactory.newInstance(); Transformer trans = tf.newTransformer(); trans.transform(new javax.xml.transform.dom.DOMSource(doc), new javax.xml.transform.stream.StreamResult(System.out)); }}
Python :
库是一个不错的选择。它提供了对XML签名和加密的全面支持。
import xmlsecfrom lxml import etree# 1. 加载 XML 文档with open("document.xml", "r") as f: xml_data = f.read()root = etree.fromstring(xml_data.encode('utf-8'))# 2. 加载密钥with open("private.pem", "r") as f: private_key = f.read()# 3. 创建 XML Security Contextctx = xmlsec.DSigCtx()# 4. 加载密钥到 Contextkey = xmlsec.Key.from_memory(private_key, xmlsec.KeyDataFormat.PEM)ctx.sign_key = key# 5. 找到 Signature 节点 (如果已经存在,否则创建)signature_node = xmlsec.tree.find_node(root, xmlsec.constants.NodeSignature)if signature_node is None: signature_node = xmlsec.template.create(root, xmlsec.constants.TransformExclC14N11, xmlsec.constants.SigRsaSha256) root.append(signature_node) ref = xmlsec.template.add_reference(signature_node, xmlsec.constants.TransformSha256, uri=""); xmlsec.template.add_transform(ref, xmlsec.constants.TransformEnveloped) keyinfo = xmlsec.template.ensure_key_info(signature_node) xmlsec.template.add_key_name(keyinfo)# 6. 签名 XML 文档ctx.sign(signature_node)# 7. 输出签名后的 XML 文档print(etree.tostring(root, pretty_print=True).decode('utf-8'))
C# (.NET) : .NET Framework 提供了
System.Security.Cryptography.Xml
命名空间,包含了XML签名相关的类。
using System;using System.IO;using System.Security.Cryptography;using System.Security.Cryptography.X509Certificates;using System.Security.Cryptography.Xml;using System.Xml;public class XMLSigner { public static void Main(string[] args) { try { // 1. 加载 XML 文档 XmlDocument doc = new XmlDocument(); doc.Load("document.xml"); // 2. 加载证书 X509Certificate2 cert = new X509Certificate2("certificate.pfx", "password"); // 替换为你的证书路径和密码 // 3. 创建 SignedXml 对象 SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = cert.PrivateKey; // 4. 创建 Reference 对象 Reference reference = new Reference(); reference.Uri = ""; // 签名整个文档 // 5. 添加转换 XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // 6. 将 Reference 添加到 SignedXml signedXml.AddReference(reference); // 7. 创建 KeyInfo 对象 KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); // 8. 将 KeyInfo 添加到 SignedXml signedXml.KeyInfo = keyInfo; // 9. 计算签名 signedXml.ComputeSignature(); // 10. 获取 XML 签名 XmlElement xmlDigitalSignature = signedXml.GetXml(); // 11. 将签名添加到 XML 文档 doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); // 12. 保存签名后的 XML 文档 doc.Save("signed_document.xml"); Console.WriteLine("XML 文档已成功签名并保存为 signed_document.xml"); } catch (Exception e) { Console.WriteLine("发生错误: " + e.Message); } }}
这些示例代码展示了如何使用不同的编程语言和库来生成XML签名。验证过程类似,需要加载签名、提取公钥或证书,并使用相同的算法验证签名值。
XML签名在哪些场景下应用广泛?
XML签名在安全性要求较高的场景下应用广泛,例如:
电子发票 : 确保发票的真实性和完整性,防止篡改。
电子病历 : 保护患者隐私,防止病历被非法修改。
金融交易 : 确保交易数据的安全性和不可抵赖性。
软件更新 : 验证软件更新包的来源和完整性,防止恶意软件传播。
Web Services 安全 : 在SOAP消息中使用XML签名来保证消息的完整性和身份验证。
选择合适的签名算法和密钥长度至关重要,并且需要定期更新密钥以应对新的安全威胁。
以上就是XML签名(XML Signature)的基本结构和作用是什么?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1430111.html