xml签名通过在xml文档中添加“数字指纹”来确保其完整性和来源可靠性。1. 其核心是<signature>元素,包含< signedinfo>(含<canonicalizationmethod>、<signaturemethod>、<reference>等子元素)、<signaturevalue>和<keyinfo>;2. 支持三种签名模式:enveloped signature(签名嵌入文档内部)、enveloping signature(签名包裹内容)、detached signature(签名与内容分离);3. 可使用java的javax.xml.crypto、python的xmlsec、c#的system.security.cryptography.xml等库实现签名生成与验证;4. 广泛应用于电子发票、电子病历、金融交易、软件更新和web services安全等场景,确保数据不可篡改和身份可信。选择强哈希算法(如sha256)和足够密钥长度并定期更新密钥是保障安全的关键措施。

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文档可能如下所示(简化版):
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<message>Hello, world!</message>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 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号