如何创建公钥/私钥对并将其安全地存储到密钥容器中?

时间:2017-06-22 19:15:06

标签: c# security cryptography

我一直在尝试做一些简单的加密练习,但我很难过。到目前为止,我已经能够生成一对公钥和私钥,但我还没有弄清楚如何安全地存储它们或使它们在单个会话之后持续存在。在我的研究中,我听说过这个称为“密钥容器”的东西,它允许这些密钥(安全地)持续超过单个会话并在以后检索。

不幸的是,密码学很复杂,所以每次我认为我已经找到了一些东西,它给了我另外五个问题,在我能理解我在做什么之前必须回答这个问题。在这一点上,我的头脑正在游泳所有这些信息,我在理解这一切时遇到了一些麻烦。所以......

我希望看到一个代码示例,它创建一个公钥/私钥对,将它们保存在密钥容器中,然后检索它们。如果可能的话,我还希望看到一些代码从一个假定已经存在的密钥容器中检索公钥和私钥。对于约束,假设Visual Studio C#正在Windows 10 OS上的.NET框架中使用。

除非有更安全的方法,否则我更倾向于使用RSA加密。

我几乎可以肯定,这或多或少是一个重复的问题,但如果是这样,那么我还没有找到原件。

1 个答案:

答案 0 :(得分:0)

借用a corefx test(和同一档案中的其他代码):

// Ideally you use a name that won't ever be used by someone else.
// Certificate import names its keys GUIDs, but then has to remember what they were.
const string KeyName = "SomePersistedKey";
const int Size = 2048; // Or whatever.

CNG:

CngKey key = null;

try
{
    key = CngKey.Open(KeyName);
}
catch (CryptographicException)
{
    // This is only in the catch block to avoid a scrollbar.
    CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
    {
        ExportPolicy = CngExportPolicies.None, // Or whatever.
        Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
        KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
        Parameters =
        {
            new CngProperty("Length", BitConverter.GetBytes(Size), CngPropertyOptions.None),
        }
    };

    cngKey = CngKey.Create(CngAlgorithm.Rsa, KeyName, creationParameters);
}

using (cngKey)
using (RSA rsa = new RSACng(cngKey))
{
    // Tada.
}

或者,如果你需要坚持使用CAPI(希望不是):

const int PROV_RSA_AES = 24;

CspParameters cspParameters = new CspParameters(PROV_RSA_AES)
{
    KeyNumber = (int)KeyNumber.Exchange,
    KeyContainerName = KeyName,
    Flags = CspProviderFlags.UseNonExportableKey, // Or whatever.
};

// This constructor is open-or-create since flags didn't asset ExistingOnly.
using (RSA rsa = new RSACryptoServiceProvider(Size, cspParameters))
{
    // tada.  Use CNG instead, if you can.
}