仅从 public 键创建 RSACryptoServiceProvider

Create RSACryptoServiceProvider from public key ONLY

我正在使用密钥对来签署我的 XML(使用 SignedXml)并将 public 密钥作为嵌入式资源嵌入到我的应用程序中。

这是我如何创建密钥对

sn -k Warehouse.snk
sn -p Warehouse.snk WarehousePublic.snk

当我尝试读取 WarehousePublic.snk 时,我得到一个异常 提供程序版本错误。

这是我的代码:

using (Stream stream = assembly.GetManifestResourceStream("WareApp.Resources.WarehousePublic.snk"))
{
    byte[] bytes = new byte[stream.Length];
    stream.Read(bytes, 0, bytes.Length);

    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {
        rsa.ImportCspBlob(bytes);  //the exception occurred here

        ...
        ...
        ...
    }
}

有没有办法仅从 public 密钥创建 RSACryptoServiceProvider

我也试过使用 X509Certificate2

X509Certificate2 cert = new X509Certificate2(bytes);  //I got exception here
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert2.PublicKey.Key;

但出现异常找不到请求的对象。

有什么想法吗?

谢谢

我认为不支持使用 SN 生成签名证书(至少使用 RSACryptoServiceProvider)。我认为这可以解释错误。您在 Windows 中寻找的是一个 .PFX 文件(即带密钥的证书)和 .CER 文件(没有私钥的证书)。

SN(MSDN link) doesn't provide security, and is only used for identity. You can use IIS or makecert.exe 生成一个自签名证书,该证书应该与您正在尝试做的事情一起工作(即 .PFX 文件和/或证书已经导入到 Windows 证书存储)。然后您可以从中提取 .CER 文件并将其用于您的项目。

我会接受 Shaamaan 的回答,因为他是“一半”是对的。您实际上可以使用 SN 来签署证书。 ImportCspBlob() 行得通!但是,当您尝试导入使用 sn -p Warehouse.snk WarehousePublic.snk 生成的 public 密钥时,它将不起作用。

为了使其工作,您需要使用 RSACryptoServiceProvider.ToXmlString(false) 在 XML 中生成 public 密钥并将其嵌入为 "embedded resources"。

我所做的是创建一个控制台应用程序。只需在下面剪切并粘贴我的代码即可在 XML 文件中生成 public 密钥。

class Program
{
    static void Main(string[] args)
    {
        if (args.Length < 2)
        {
            Console.WriteLine("Invalid Argument");
            Console.WriteLine("Usage:");
            Console.WriteLine("\tExtractPublicKey [Input SNK File] [Output XML File]");
            return;
        }

        using (FileStream fs = File.Open(args[0], FileMode.Open, FileAccess.Read))
        {
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, bytes.Length);

            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(bytes);
                using (StreamWriter sw = new StreamWriter(File.Open(args[1], FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)))
                    sw.Write(rsa.ToXmlString(false));
            }
        }
    }
}

编译后,要使用可执行文件只需调用: ExtractPublicKey.exe [SNK File with Private Key] [Output Public Key in XML File]

要使用嵌入式证书,只需执行以下操作:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(stream.ReadToEnd());

我希望这对遇到类似问题的人有所帮助。

干杯

已更新

应该遵循 Shaamaan 的回答。请通过 MSDN link 阅读 Shaamaan 评论。他的回答是正确的,因为他不仅提供了正确的安全方法,而且还告诉我为什么 SN 不是正确的安全工具。谢谢 Shaamaan!