Last active
May 1, 2019 08:36
-
-
Save daisukenishino2/69074e571cf89c23cce6d1522abc67e5 to your computer and use it in GitHub Desktop.
ネストしたXMLの署名・検証処理の問題の確認用コード。https://github.com/AndersAbel/DualXmlDsigBug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Security.Cryptography; | |
using System.Security.Cryptography.X509Certificates; | |
using System.Security.Cryptography.Xml; | |
using System.Xml; | |
namespace DualXmlDsigBug | |
{ | |
public static class SigningTest | |
{ | |
public static void SignAndVerify() | |
{ | |
var xml = "" | |
+ "<xml>" | |
+ " <a ID=\"a\">" | |
+ " <b ID=\"b\">" | |
+ " <c/>" | |
+ " </b>" | |
+ " </a>" | |
+ "</xml>"; | |
var xmlDoc = new XmlDocument(); | |
xmlDoc.LoadXml(xml); | |
using (var csp = new RSACryptoServiceProvider()) | |
{ | |
#region 子ノード b のXML署名・検証 | |
#region 子ノード b のXML署名 | |
Console.WriteLine("Signing child b node..."); | |
SignedXml signedXmlB = new SignedXml(xmlDoc) { SigningKey = csp }; | |
#region Reference要素 | |
// 子ノード b をポイント | |
Reference referenceB = new Reference("#b"); | |
// Add Transform | |
referenceB.AddTransform(new XmlDsigEnvelopedSignatureTransform()); | |
// Add Transform | |
referenceB.AddTransform(new XmlDsigExcC14NTransform()); | |
// Add Reference | |
signedXmlB.AddReference(referenceB); | |
#endregion | |
// 子ノード b のXML署名の生成 | |
signedXmlB.ComputeSignature(); | |
// 子ノード b のXML署名を子ノード b 直下に追加 | |
XmlNode signatureNodeB = xmlDoc.ImportNode(signedXmlB.GetXml(), true); | |
xmlDoc.SelectSingleNode("//b").AppendChild(signatureNodeB); | |
#endregion | |
#region 子ノード b のXML検証 | |
signedXmlB.LoadXml(signatureNodeB as XmlElement); | |
XmlNode xmlnode = xmlDoc.SelectSingleNode("//b"); | |
Console.WriteLine("Check signature B: " + CheckSignature(xmlnode, csp)); | |
#endregion | |
#endregion | |
//--------------------------------------------- | |
#region 親ノード a のXML署名・検証 | |
#region 親ノード a のXML署名 | |
Console.WriteLine("Signing parent a node..."); | |
SignedXml signedXmlA = new SignedXml(xmlDoc) { SigningKey = csp }; | |
#region Reference要素 | |
// 親ノード a をポイント | |
Reference referenceA = new Reference("#a"); | |
// Add Transform | |
referenceA.AddTransform(new XmlDsigEnvelopedSignatureTransform()); | |
// Add Transform | |
referenceA.AddTransform(new XmlDsigExcC14NTransform()); | |
// Add Reference | |
signedXmlA.AddReference(referenceA); | |
#endregion | |
// 親ノード a のXML署名の生成 | |
signedXmlA.ComputeSignature(); | |
// 親ノード a XML署名を親ノード a 直下に追加 | |
XmlNode signatureNodeA = xmlDoc.ImportNode(signedXmlA.GetXml(), true); | |
xmlDoc.SelectSingleNode("//a").AppendChild(signatureNodeA); | |
#endregion | |
string temp = xmlDoc.OuterXml; | |
#region 親ノード a のXML検証 | |
Console.WriteLine("Check signature A: " + CheckSignature(xmlDoc.SelectSingleNode("//a"), csp)); | |
Console.WriteLine("Check signature B: " + CheckSignature(xmlDoc.SelectSingleNode("//b"), csp)); | |
#endregion | |
#endregion | |
// ネストが問題になるようなら、 | |
// 子ノード b だけ抽出して計算すればイイ | |
// ネストした、子ノード b のXML検証 | |
var childDoc = new XmlDocument(); | |
childDoc.LoadXml(xmlDoc.SelectSingleNode("//b").OuterXml); | |
Console.WriteLine("Check signature B, in own document: " + CheckSignature(childDoc.SelectSingleNode("//b"), csp)); | |
} | |
} | |
private static bool CheckSignature(XmlNode xmlNode, RSACryptoServiceProvider csp) | |
{ | |
// 署名ノードの直下のSignatureを取り出して、signedXml.LoadXmlする。 | |
var signedXml = new SignedXml(xmlNode.OwnerDocument); | |
signedXml.LoadXml(xmlNode["Signature"] as XmlElement); | |
// XML検証 | |
return signedXml.CheckSignature(csp); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
経緯
SignedXmlクラスの実装に問題があり、
ネストした複数のXML署名が Verify できないらしい。
https://techinfoofmicrosofttech.osscons.jp/index.php?SAML%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%80%82#k3724cb3
結果
使用する範囲(SAML2 Assertionの署名・検証)で、問題なく動作するものと思われる。
出力
ConsoleのOutput。
SignedXml
署名したXML(正しく検証できた。)