我想使用公共/私人加密,我的网络应用会使用私钥对xml文档或数据进行签名,并且将使用公钥在应用程序中进行验证,
是否可以在.net 2.0托管环境中使用RSACryptoServiceProvider,如果不是其他可能的解决方法?
答案 0 :(得分:1)
是的,很有可能。
如果您导出用于数据签名的证书到.pfx文件,您可以通过这种方式获取数据。
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文件的密码,您应该在应用程序配置设置中store securely。您可以使用.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文档不受密码保护,并且不安全。 (read the doc on ToXmlString())您可以加密此XML文档,就像加密任何其他设置一样。 (search)
在这种情况下,你可以这样做来获取你的csp:
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
csp.FromXmlString(keyPairXml);
答案 1 :(得分:0)
答案 2 :(得分:0)
是的,可以在托管环境中使用它,但要注意多线程issues relating to its use
这些是一些最小化ASP.NET中的线程问题的建议:
创建RSACryptoServiceProvider对象时设置CspParameters.KeyContainer名称。永远不要使用默认的! 这容易造成商店腐败。我们已经讨论了这个问题。
尽可能在RSACrytpoServiceProvider对象上显式调用Dispose。这样,我们就不依赖垃圾收集器了 “最终”释放了CSP。
在创建RSACryptoServiceProvider时在CspParameters.Flags中设置UseMachineKeyStore。此标志告诉RSACryptoServiceProvider 使用“机器位置”来存储RSA公钥/私钥对 “当前用户”位置。这相当于打电话 带有CRYPT_MACHINE_KEYSET的CryptAcquireContext API。确保所有的 使用RSA实例的线程在同一帐户下运行。
不要将RSACryptoServiceProvider.PersistKeyInCSP设置为False。这将导致在RSA实例时删除密钥容器 释放或垃圾收集。如果多个线程正在尝试 访问相同的命名密钥容器,该命名密钥的状态 容器可能处于临时清理状态,但不可能 获得的。
- 醇>
另一个选择是我们在Web应用程序中实例化一次RSACryptoServiceProvider 初始化然后使用相同的实例进行加密或 在像锁(即Mutex)这样的关键部分下进行解密。这个会 同时避免多次从密钥容器中重新获取密钥容器 过程