0

0

XML上传的数字签名如何生成和验证

月夜之吻

月夜之吻

发布时间:2026-02-10 08:56:02

|

766人浏览过

|

来源于php中文网

原创

XML数字签名必须遵循W3C规范预处理,包括规范化(C14N)、节点选择与结构序列化,不可直接哈希原始XML字符串;推荐使用signxml(Python)、javax.xml.crypto.dsig(Java)或xml-crypto(Node.js)等标准库实现,确保C14N算法、URI作用域、命名空间、密钥类型与证书链严格匹配。

xml上传的数字签名如何生成和验证

XML数字签名生成依赖标准库,不是手算哈希

XML数字签名(XML-DSig)不是简单对整个XML做SHA256再加密——它必须按W3C规范预处理:规范化(Canonicalization)、选择签名节点、序列化签名结构。直接用 hashlib.sha256()openssl dgst 对原始XML字符串签名,验证时必然失败。

实操建议:

  • Python 优先用 lxml.etree + signxml 库,它自动处理 C14N(如 InclusiveNamespaces)、Reference URI 解析、SignatureValue 填充等细节
  • Java 推荐 javax.xml.crypto.dsig(JDK内置),避免用低层 MessageDigest 手动拼接
  • Node.js 可用 xml-crypto,注意其默认 C14N 是 exclusive,若服务端要求 inclusive 需显式配置

签名前必须明确作用域:整个文档 vs 某个元素

XML签名可签整个文档(URI=""),也可只签某个带 Id 属性的子元素(如 URI="#order123")。验证失败常因作用域不一致:上传时签了 ,但验证方尝试验证整个文档根节点。

关键点:

  • 签名时务必确认目标节点是否已设 Id 属性(非 id,大小写敏感),且值唯一
  • 生成签名前,确保该节点在DOM中存在——如果用字符串拼接XML再解析,可能丢失属性或命名空间声明
  • 验证时,解析器需能根据 Reference/@URI 定位到对应节点;若节点被移除、重命名或 Id 被修改,验证即失败

公钥和证书链必须匹配签名算法与密钥类型

常见错误是私钥用RSA-2048签名,但验证时拿ECDSA公钥去验,或证书链不完整导致X.509验证失败。XML签名的 KeyInfo 部分常嵌入 X509Certificate,但验证方未必信任该证书。

炉米Lumi
炉米Lumi

字节跳动推出的AI模型分享社区和模型训练平台

下载

实操注意:

  • 签名算法(SignatureMethod)和摘要算法(DigestMethod)需与密钥类型对齐:RSA密钥配 http://www.w3.org/2001/04/xmldsig-more#rsa-sha256,ECDSA密钥配 http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
  • 若用自签名证书,验证方需显式加载该证书(不能只靠系统信任库)
  • KeyInfo/X509Data 中的证书顺序应为 leaf → intermediate → root;缺少中间证书时,部分验证库(如 .NET SignedXml)会静默失败

验证失败时先检查 Canonicalization 和命名空间

最隐蔽的坑是C14N(规范化)差异。同一份XML,用 exc-c14ninclusive-c14n 生成的字节流完全不同,签名自然不匹配。尤其当XML含默认命名空间(xmlns="http://example.com")时,不同C14N处理方式差异极大。

快速排查:

  • signxmlverify() 方法传 require_x509=False 参数,先绕过证书验证,聚焦签名本身
  • 导出签名前的规范化字节流(signxml.canonicalize())和验证时实际计算的字节流,用 diff 对比
  • 检查XML中所有命名空间声明是否在签名作用域内——若签名节点外有 xmlns:ds="http://www.w3.org/2000/09/xmldsig#",但签名内部未重复声明,exc-c14n 会剔除它,而 inclusive 会保留
from signxml import XMLSigner
from lxml import etree

签名示例:签带 Id 的 Order 元素

xml = b'http://www.w3.org/2000/09/xmldsig#"youjiankuohaophpcnzuojiankuohaophpcnOrder Id="order123">100' root = etree.fromstring(xml) signer = XMLSigner(method=signxml.methods.enveloped, signature_algorithm="rsa-sha256") signed_root = signer.sign( root, key=private_key, reference_uri="#order123", # 关键:指定 Id c14n_algorithm="https://www.php.cn/link/51ac520c783d88964a793e455dae3506" # 明确 C14N )

签名逻辑本身不复杂,难的是每一步都得和对方系统对齐:C14N算法、URI解析规则、命名空间处理、证书信任链——漏掉任意一环,验证就卡在“签名无效”这个笼统错误里。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1922

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

2100

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

1111

2024.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

464

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

213

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1519

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

634

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

801

2024.03.22

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

132

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号