2

我想使用公共/私人加密,我的网络应用程序将使用私钥签署 xml 文档或一段数据,并将使用公钥在应用程序中对其进行验证,

如果没有其他可能的解决方法,是否可以在 .net 2.0 托管环境中使用 RSACryptoServiceProvider?

4

3 回答 3

1

是的,很有可能。

如果您将用于数据签名的证书导出到 .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);
于 2009-07-29T07:05:54.783 回答
0

见这里: http: //www.codeproject.com/KB/security/EZRSA.aspx

于 2010-03-18T10:52:16.900 回答
0

是的,可以在托管环境中使用它,但要注意与其使用相关的多线程问题

这些是减少 ASP.NET 中的线程问题的一些建议:

  1. 创建 RSACryptoServiceProvider 对象时设置 CspParameters.KeyContainer 名称。永远不要使用默认的,永远不要!这很容易导致存储损坏。我们已经谈过了。

  2. 尽可能在 RSACrytpoServiceProvider 对象上显式调用 Dispose。这样,我们就不会依赖垃圾收集器来“最终”发布 CSP。

  3. 创建 RSACryptoServiceProvider 时,在 CspParameters.Flags 中设置 UseMachineKeyStore。此标志告诉 RSACryptoServiceProvider 使用“机器位置”来存储 RSA 公钥/私钥对而不是“当前用户”位置。这相当于使用 CRYPT_MACHINE_KEYSET 调用 CryptAcquireContext API。确保使用 RSA 实例的所有线程都在同一帐户下运行。

  4. 不要将 RSACryptoServiceProvider.PersistKeyInCSP 设置为 False。这将导致在释放 RSA 实例或进行垃圾收集时删除密钥容器。如果多个线程试图访问同一个命名密钥容器,则该命名密钥容器的状态可能处于临时清理状态并且无法获取。

  5. 另一种选择是我们将 RSACryptoServiceProvider 实例化一次,作为 Web 应用程序初始化的一部分,然后在锁(即互斥锁)等关键部分下使用相同的实例进行加密或解密。这也将避免从同一进程中多次重新获取密钥容器。

于 2012-07-03T11:15:08.680 回答