XML数字签名,就是选择出xml文件中的一些内容,然后标准化(规范化),然后对其数据流(UTF8化后)进行计算一个特征码(HASH值).具体算法很多如hash1,has256,sm3等等, 剩下的所谓签名也是很简单,就是用私钥(你的私人密码)加对这个特征码加密, 并给出一个密文。 签名的xml文件里面会记录这个算法和特征码,归一化方法,以 及那些节点参与计算特征码.
这个时候就可以分发这个xml. 称之为签名的 XML.
其他人用你的开锁工具(公钥)来开,具体就是先算特征码是否正确,然后用签名串(密文), 来解密,看那个签名串里面加密的特征码和XML明示特征码是否一致。
所谓库或SDK就是这些功能的封装,在这个过程中, 真正的焦点于选择内容与归一化。
(1) XML 签名的时候可能是选择其中一部分进行签名,第一步就是选择里面的节点内容,
可以选择一个节点,或全部内容,或者部分节点,这个按照具体的环境而定。
重点是:如果最后选择的是一个节点集合,可不可以? 理论上可以,最后特征值就是计算嘛!实际上不行的,
原因在于:多个节点按照何种顺序排序? 这个不同的语言不同的文化不同的系统可能存在差异。
因此 Reference URI 是 “”(全部)或者节点表达式,且只能选出一个节点(可能带有子节点)。
(2) XML 最初目标为计算机数据交换用,但由于各类原因,目前里面充满了为了满足人类阅读需要的各类留白和换行等符号。如何处置就是归一化,具体原理如下
对于具体元素
<data1 b="CCC" a="xxx" >xx xx</data1 >
处理方法是,首先对属性 a,b 排序,然后,对内部多余空格去除,具体属性(attr)a,b和值(value)不处理,保持原样。
最后结果如下
<data1 a="xxx" b="CCC">xx xx</data1>
不封闭的元素进行封闭 如</data> 转换为 <data></data>
节点(Node) 通常的处理就是选择节点之外内容全部去除。节点之内全部保留。这个方法有个缺点,子节点之间的换行和留白会保留。
还有一种通用的方法,就是去除元素之外的所有空白和换行等符号。这个相对非常简单,不需要考虑什么换行留白之类,便于系统之间通用。
(4) 其实注释处理等,特殊字符之类细则很多(C14N)等,但对于普通的需求xml一般没有什么命名空间和其他的东西。
这些问题弄清了,其他都是小问题,至于后续的什么封装,签名,验签什么的都是小case。
看到这里,是不是觉得就是小把戏? 其实就是小把戏。