XML DSIG 検証
-
12-09-2019 - |
質問
XML ドキュメントにデジタル署名し、2 台の異なるマシンで検証しています (1 台のマシンで署名し、別のマシンで検証します)。
CSharp.Net で XML DSIG を検証するために次のことを行っています。
public static Boolean VerifyXml(XmlDocument document)
{
document.PreserveWhitespace = true;
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
// Create a new RSA signing key and save it in the container.
//**Earlier was getting exception here in rsaKey object**
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(document);
// Find the "Signature" node and create a new
// XmlNodeList object.
// It's guaranteed that there's always exists a signature
XmlNodeList nodeList = document.GetElementsByTagName("Signature");
// Load the <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
bool isDone = signedXml.CheckSignature(rsaKey); //**This is returning false.**
return isDone;
}
当初、Web アプリケーションがキー コンテナーにアクセスしようとすると、PermissionDenied 例外が発生していました。しかし、私は 一時的に アプリケーション ユーザーと IIS ユーザーを管理者ロールに追加し、CasPol を使用して Web アプリケーションに FullTrust セキュリティ ポリシーを割り当てました。
Q1:[最初の質問は、これを克服する最善の方法は何ですか??Web アプリケーションに完全な信頼を割り当て、ユーザーを管理者ロールに追加するのは、たとえ機能するとしても、賢明なアイデアではないことはわかっています。
2番目の質問は、 signedXml.CheckSignature(rsaKey);
falseを返します。私の理解によると、XMLドキュメントは別のマシンでデジタル署名されているため、署名に使用されたMACはそのマシンにKEYコンテナ名「XML_DSIG_RSA_KEY」で保存されていますが、ホストマシンで署名を検証しようとすると、別のMACが使用されます。生成され、ホスト マシン上のコンテナ名「XML_DSIG_RSA_KEY」に保存されたため、デジタル署名は検証されませんでした。
Q2:この仮定は正しいでしょうか??そしてこれに対処する最善の方法は何ですか...その場合、証明書を使用して XML ドキュメントにデジタル署名し、それを検証する必要があります。証明書に DSIG XML ドキュメントを添付する必要がありますか????
解決
まず 2 番目の質問に答えると、次のようになります。XML を次のように検証したいとします。 公共 署名に使用された RSA キー ペアの一部。したがって、検証マシン上の公開キーをすでに所有している (そして信頼している) か、公開キーを含む証明書を XML で送信し (XML 署名構造内に保存できます)、その証明書が安全であることを検証する必要があります。信頼できる認証局によって発行されたもの。
最初のケースを実装するには、次のように呼び出すことができます ToXmlString(false)
送信側でキーを入力し、結果をファイルに保存し、このファイルを受信側で保持します。次に、受信側でファイルを読み取り、次のように呼び出します。
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
rsaKey.ImportFromXml(publicKeyFromFile);
2 番目のケースは、次のように証明書を取得し、署名側の署名に追加することで実行できます。
KeyInfo keyInfo = new KeyInfo();
X509Certificate cert = // load certificate
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
証明書が信頼できる場合は、次を呼び出すだけで受信側の署名を検証できます。
bool isDone = signedXml.CheckSignature();
最初の質問に答えるには:秘密キー ストアへのアクセスを試行しなくなったら (これは、以前と同じように RSACryptoServiceProvider コンストラクターを呼び出して実行していました)、完全な信頼なしで実行できるはずです。