从RSACryptoServiceProvider转换为RSACng

时间:2018-06-04 22:01:43

标签: c# .net cryptography public-key-encryption

我目前正在使用RSACryptoServiceProvider,我想更改为RSACng。我用它来签名数据。更改的原因是我正在使用Pkcs1填充,我知道Pss填充是首选。我们正在接受安全审核。

我的问题是如何实例化RSACng以便每次使用相同的私钥/公钥?

使用RSACryptoServiceProvider我正在做:

CspParameters cp = new CspParameters();  
cp.KeyContainerName = "ContainerName";  
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp);

传入容器名称意味着它使用持久存储在计算机上的容器存储中的密钥。

使用RSACng,我尝试了这个,但我得到一个例外:“不支持请求的操作”

RSACng RSA = new RSACng(CngKey.Create(CngAlgorithm.Sha256, ContainerName));

我只需要能够传递商店密钥名称,以便每次使用相同的密钥而不是生成新密钥。

1 个答案:

答案 0 :(得分:1)

如果要使用CNG创建命名/持久化RSA密钥:

private static RSA CreatePersistedRSAKey(string name, int keySizeInBits)
{
    CngKeyCreationParameters creationParameters = new CngKeyCreationParameters
    {
        // This is what an ephemeral key would have had
        // (allows ExportParameters(true) to succeed). Adjust as desired.
        //
        // The default is not exportable (only applies to the private key)
        ExportPolicy =
            CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport,
    };

    creationParameters.Parameters.Add(
        new CngProperty(
            "Length",
            BitConverter.GetBytes(keySizeInBits),
            CngPropertyOptions.Persist));

    // RSACng will extract the data it needs from this key object,
    // but doesn't take ownership
    using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, name, creationParameters))
    {
        return new RSACng(key);
    }
}

这会跳过你在CngKey.Open调用时尝试/捕获的部分,或者可能想删除密钥(用CngKey.Open打开它,并在CngKey实例上调用Delete)。

(在net46中添加了CngAlgorithm.Rsa。如果您使用的是旧版本,则等效值为new CngAlgorithm("RSA")