ルート ノードが RSA+SHA2 署名で署名されている XML ドキュメントがあり、これには RSA+SHA2 で個別に署名された XML 要素が含まれています。
- ルート ノードの署名が無効です
- 子ノードの個別の署名が無効です
署名された子ノードを新しい XML ファイルにコピーし、名前空間のスコープを維持するために xmlns: 宣言もそのノードに移動すると、
- 署名は有効です
XML 構造は次のようなものです。実際の XML は、署名付き SAML2 アサーションを含む署名付き SAML2 ArtifactResolve 要素です。
<Root id="_1">
<ds:Signature reference="_1" />
<Child id="_2">
<ds:Signature reference="_2" />
</Child>
</Root>
これらすべてを検証するために使用されるコードは、SignedXml クラスという非常に単純なものです。
SignedXml signedDocument = new SignedXml(document.DocumentElement);
signedDocument.LoadXml(GetSignatureElement(document.DocumentElement));
Console.WriteLine("Document valid: {0}",
signedDocument.CheckSignature(cert, true)); // returns false
ここでの主な問題は、ノードを新しい XML ファイルにコピーすることでノードを検証できるという奇妙な動作です。XPath を介してそのノードにクエリを実行し、それを SignedXml にロードすると失敗します。
XmlElement element = (XmlElement)document.SelectSingleNode("//Child");
SignedXml signedDocument = new SignedXml(element);
signedDocument.LoadXml(GetSignatureElement(element));
Console.WriteLine("Element valid: {0}",
signedDocument.CheckSignature(cert, true)); // returns false
ここで、SignedXml に失敗できる設定が大量にあるとしますが、それほど多くはありません。Xml を読み込み、署名を読み込み、検証します。
なぜこの振る舞いがそのままなのか、手がかりを持っている人はいますか? XmlDocument で PreserveWhitespace=true を使用しようとしましたが、それは役に立ちませんでした。
とても有難い!
ウーター