signedxml.CheckSignatureは秘密鍵で確認した場合のみTRUEを返す
-
20-12-2019 - |
質問
私はいくつかの類似の質問を見ましたが、それは私が尋ねているものを正確にアドレスに対処していません。
XMLに署名しようとしていますから、C#。
を使って公開鍵で確認してください。 XMLに署名し、キーをXMLにエクスポートします。その後、キーと署名付きXMLを別のコンピュータに取り出し、rsa.FromXmlString(doc.InnerXml)
を使用してキーをインポートし、XMLシグネチャを確認します。
Publicキーと秘密鍵の両方をrsa.ToXmlString(True)
を使用してXMLにエクスポートすると機能します。ただし、rsa.ToXmlString(False)
を使用して公開鍵のみをエクスポートします。公開鍵のみをエクスポートして2番目のコンピュータにインポートし、XMLシグネチャを検証しようとすると、署名は無効です。
最初に、公開鍵のみで署名付きXMLを検証できるようにする必要がありますか?
2番目の場合、XML機能の確認のみがPUB / PRIVキーのペアでのみ機能し、公開鍵だけではないのですか?
この問題をデバッグする方法についての知恵はありますか? signedXml.CheckSignature(Key);
が失敗した理由に関する情報を提供していないため、他に何をするのかわかりません。
マイインポートキー、エクスポートキー、符号XML、およびXML関数の確認は以下の通りです。もっと情報が必要な場合は教えてください。
public static void ImportKeyFromFile(string ContainerName, string inputFile)
{
try
{
// Create new XmlDocument.
XmlDocument doc = new XmlDocument();
// Load XML Document.
doc.Load(inputFile);
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container MyKeyContainerName.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
// Get RSA Parameters from xml document.
rsa.FromXmlString(doc.InnerXml);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public static void ExportKeyToFile(string ContainerName, string outputPath, bool private_key)
{
try
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container MyKeyContainerName.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
// Create new XmlDocument.
XmlDocument doc = new XmlDocument();
// Store rsa key.
doc.InnerXml = rsa.ToXmlString(private_key);
// Save Document.
doc.Save(outputPath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
public static void SignXml(XmlDocument xmlDoc, RSA Key)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
. 解決
問題は、パブリックキーをキーコンテナに保存できないためです。公開鍵だけで署名を確認するには、rsa.FromXmlString
を使用してXMLからキーをインポートする必要があります。次にRSAを直接検証署名機能に渡す必要があります。公開鍵をキーコンテナに保存して後で取得しようとすると、新しいキーの作成が終わるだけです。
公開鍵を保存する方法機械レベルのRSAキーコンテナ