ドキュメントに署名するときに使用されるxslt変換は、署名の計算時にソースXMLのノードがどのように選択されるかに関連しています。
Daveによるこの質問/回答は、xpath2を使用したXMLドキュメントの一部の署名に関連しています。この回答のSeanMullansの投稿へのリンクは、xpath式の評価がノードごとに行われるため、xpath2がドキュメントの一部に署名するのにより適していることを示唆しています。
したがって、 sun dsigの例に基づいて、次を使用して参照の作成を置き換えることができます。
List<XPathType> xpaths = new ArrayList<XPathType>();
xpaths.add(new XPathType("//r1/user", XPathType.Filter.INTERSECT));
Reference ref = fac.newReference
("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList
(fac.newTransform(Transform.XPATH2,
new XPathFilter2ParameterSpec(xpaths))),
null, null);
これにより、// r1 / userを署名で保護しながら、ドキュメントの残りの部分を変更できます。
xpath / xpath2の選択に関する問題は、/ some / node / that / does / not/existの署名を生成できることです。テストドキュメントを変更し、署名が期待どおりに機能していることを確認するのは正しいことです。
署名を生成し、検証前にxmlノードを改ざんすることにより、テストプログラムでドキュメントをテストできます。
NodeList nlt = doc.getElementsByTagName("user");
nlt.item(0).getFirstChild().setTextContent("Something else");
xpathセレクターのより信頼性の高い代替手段は、次のように署名したいxmlドキュメント要素にIDを配置することです。
<r1>
<user id="sign1">asd</user>
<person>ghi</person>
</r1>
次に、このIDをエンベロープ転送の最初のパラメーターのURIとして参照します。
Reference ref = fac.newReference
("#sign1", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList
(fac.newTransform(Transform.ENVELOPED,(TransformParameterSpec) null)),
null, null);
出力の場合、署名操作により、メモリにロードしたDOMに新しい署名要素が追加されます。次のように変換することで、出力をストリーミングできます。
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.transform(new DOMSource(doc), new StreamResult(System.out));