xml签名通过在xml文档中添加“数字指纹”来确保其完整性和来源可靠性。1. 其核心是
XML签名,简单来说,就是给XML文档加上一个“数字指纹”,确保文档的完整性和来源可靠性。它能防止文档被篡改,并验证签名者的身份。
解决方案:
XML签名的核心在于
<Signature>
<SignedInfo>
<CanonicalizationMethod>
http://www.w3.org/2001/10/xml-exc-c14n#
<SignatureMethod>
http://www.w3.org/2001/09/xmldsig#rsa-sha1
<Reference>
<Reference>
URI
<Transforms>
<DigestMethod>
http://www.w3.org/2001/04/xmlenc#sha256
<DigestValue>
<SignatureValue>
<SignedInfo>
<KeyInfo>
<X509Data>
<KeyValue>
<RetrievalMethod>
举个例子,假设我们要签名一个简单的XML文档:
<message>Hello, world!</message>
签名后的XML文档可能如下所示(简化版):
<SignedInfo> <message>Hello, world!</message><Transforms> <SignatureValue>... <KeyInfo> <X509Data><DigestValue>... ...
XML签名有哪些不同的签名模式?
XML签名支持多种签名模式,主要区别在于
<Signature>
Enveloped Signature (信封签名):
<Signature>
Enveloping Signature (内含签名):
<Signature>
<Signature>
Detached Signature (分离签名):
<Signature>
<Signature>
URI
选择哪种签名模式取决于具体的需求。Enveloped Signature 适合签名整个XML文档,而 Detached Signature 适合签名外部资源。
如何使用编程语言生成和验证XML签名?
许多编程语言都提供了XML签名库,可以简化签名和验证过程。
Java: Java的内置库
javax.xml.crypto
// 使用 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<Object> 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:
xmlsec
import xmlsec from 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 Context ctx = xmlsec.DSigCtx() # 4. 加载密钥到 Context key = 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
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)的基本结构和作用是什么?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号