Webアプリが秘密鍵を使用してxmlドキュメントまたはデータに署名し、公開鍵を使用してアプリケーションで検証される公開/秘密暗号化を使用したいのですが、
他に考えられる回避策がない場合、.net 2.0でホストされている環境でRSACryptoServiceProviderを使用することは可能ですか?
Webアプリが秘密鍵を使用してxmlドキュメントまたはデータに署名し、公開鍵を使用してアプリケーションで検証される公開/秘密暗号化を使用したいのですが、
他に考えられる回避策がない場合、.net 2.0でホストされている環境でRSACryptoServiceProviderを使用することは可能ですか?
はい、かなり可能です。
データ署名に使用する証明書を .pfx ファイルにエクスポートすると、この方法で digsig を取得できます。
using System;
using System.Xml;
using System.Reflection;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;
// ...
static void SignWithPfxPrivateKey()
{
X509Certificate2 certificate = new X509Certificate2(certFile, pfxPassword);
RSACryptoServiceProvider rsaCsp = (RSACryptoServiceProvider) certificate.PrivateKey;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
if (loadFromString)
xmlDoc.LoadXml(rawXml); // load from a string
else
xmlDoc.Load("test.xml"); // load from a document
// Sign the XML document.
SignXml(xmlDoc, rsaCsp);
// Save the document.
xmlDoc.Save("RsaSigningWithCert.xml");
xmlDoc.Save(new XTWFND(Console.Out));
}
public static void SignXml(XmlDocument Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(Doc);
// 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.
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
}
これを使用するには、ホストされたサーバーに .pfx ファイルをアップロードする必要があります。その pfx ファイルのパスワードも必要です。これは、アプリケーションの構成設定に安全に保存する必要があります。.cer ファイルでも同様のことができます。
通常の XML から RSA キーをロードすることもできます。次のように、ローカルマシン ストアからキーをロードしてインスタンス化した RSACryptoServiceProvider がある場合:
// Get the key pair from the key store.
CspParameters parms = new CspParameters(1);
parms.Flags = CspProviderFlags.UseMachineKeyStore;
parms.KeyContainerName = "SnapConfig";
parms.KeyNumber = 2;
RsaCsp = new RSACryptoServiceProvider(parms);
...次に、そのキーをエクスポートできます
RsaCsp.ToXmlString(true);
結果は、ファイルに保存してホスト サーバーにアップロードできる XML ドキュメントを含む文字列です。キー ペアのストアとしての .pfx ファイルの代替。 注意してください。この xml ドキュメントはパスワードで保護されていないため、安全ではありません。( ToXmlString() のドキュメントを参照してください)この XML ドキュメントは、他の設定を暗号化するのと同じように暗号化できます。(検索)
その場合、これを実行して csp を取得できます。
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
csp.FromXmlString(keyPairXml);
ここを参照してください: http://www.codeproject.com/KB/security/EZRSA.aspx
はい、ホストされた環境でこれを使用することは可能ですが、その使用に関連するマルチスレッドの問題に注意してください
ASP.NET でのスレッドの問題を最小限に抑えるためのいくつかの提案を次に示します。
RSACryptoServiceProvider オブジェクトを作成するときに CspParameters.KeyContainer 名を設定します。デフォルトのものは絶対に使用しないでください。これにより、ストアが破損する傾向があります。これについてはすでに話しました。
可能であれば、RSACrytpoServiceProvider オブジェクトで Dispose を明示的に呼び出します。このように、CSP を「最終的に」解放するためにガベージ コレクターに依存することはありません。
RSACryptoServiceProvider を作成するときに、CspParameters.Flags で UseMachineKeyStore を設定します。このフラグは、RSACryptoServiceProvider に、「現在のユーザー」の場所ではなく、RSA 公開鍵と秘密鍵のペアを格納するために「マシンの場所」を使用するように指示します。これは、CRYPT_MACHINE_KEYSET で CryptAcquireContext API を呼び出すことと同じです。RSA インスタンスを使用するすべてのスレッドが同じアカウントで実行されていることを確認してください。
RSACryptoServiceProvider.PersistKeyInCSP を False に設定しないでください。これにより、RSA インスタンスが解放されるかガベージ コレクションが行われると、キー コンテナーが削除されます。複数のスレッドが同じ名前付きキー コンテナーにアクセスしようとすると、その名前付きキー コンテナーの状態が一時的にクリーンアップされた状態になり、取得できなくなる可能性があります。
もう 1 つのオプションは、Web アプリケーションの初期化の一部として RSACryptoServiceProvider をインスタンス化し、ロックなどのクリティカル セクション (Mutex など) で暗号化または復号化に同じインスタンスを使用することです。これにより、同じプロセスからキー コンテナーを複数回再取得することも回避できます。