存储 RSA 密钥并在 .Net core 中使用它的最佳方法(寻找跨平台解决方案)

Dev*_*unt 11 c# rsa .net-core

我目前正在使用此链接将我的 RSA 密钥存储在 Windows 密钥容器(机器级)中,并且工作正常,但我正在寻找一种适用于 Linux 和 Windows 的方法,因为我肯定会在 Linux 上部署此项目。

public static void StoreRSAKey(string containerName, string xmlKey)
{
#pragma warning disable CA1416 // Validate platform compatibility
    var parameters = new CspParameters
    {
        KeyContainerName = containerName
    };
#pragma warning restore CA1416 // Validate platform compatibility
    parameters.Flags = CspProviderFlags.UseMachineKeyStore;

    using RSACryptoServiceProvider? rsa = new RSACryptoServiceProvider(parameters);
    rsa.FromXmlString(xmlKey);
}
Run Code Online (Sandbox Code Playgroud)

我在网上找到了一些建议,但我需要更精确的解决方案。

如果有人能帮助我解决这个问题,我会很高兴。

may*_*ʎɐɯ 14

存储 RSA 密钥并在 .Net core 中使用它的最佳方法(寻找跨平台解决方案)

IMO,问题应该是,是否可以在.net core中使用RSA密钥进行跨平台?

我最近构建了开源加密和解密库,花了几个小时研究您提出的同一问题。简短的回答是不可能在 Linux 上使用 CspParameters,它适用于 Windows 操作系统(正如这个答案提到的)。并且因为答案是不可能的,所以没有最好的方法。

首先,让我们看看是否可以回答在 .net core 中使用 RSA 密钥进行跨平台的问题。

要做到这一点非常简单,您需要执行以下操作:

Rsa = RSA.Create();
Rsa.KeySize = 2048;
Run Code Online (Sandbox Code Playgroud)

这部分不需要安装库,它是netstandard2.0的一部分。

就是这样,现在要导出和导入您生成的密钥,您可以执行以下操作。

第一次时,RSA.Create()您可以导出密钥并将其存储在安全的地方以供以后使用。

导出私钥并妥善保管

Rsa.ToXmlString(true);
Run Code Online (Sandbox Code Playgroud)

导出公钥,用于加密

Rsa.ToXmlString(false);
Run Code Online (Sandbox Code Playgroud)

当您需要从本地存储导入密钥时,可以执行以下操作:

Rsa.FromXmlString(asymmetricKey);
Run Code Online (Sandbox Code Playgroud)

这是适用于 Windows、Linux 或 Mac 计算机的跨平台兼容解决方案。

还可以使用本地计算机导入证书X509Certificate2并使用其公钥进行加密和私钥进行解密。

还可以将私钥参数导入到RSAParameters,这需要一个辅助方法来翻译私钥文件中的 XML 标签:

<RSAKeyValue>
    <Modulus>xxxx...</Modulus>
    <Exponent>xxxx</Exponent>
    <P>xxxx...</P>
    <Q>xxxx...</Q>
    <DP>xxxx...</DP>
    <DQ>xxxx...</DQ>
    <InverseQ>xxxx...</InverseQ>
    <D>xxxx...</D>
</RSAKeyValue>
Run Code Online (Sandbox Code Playgroud)

但我发现它更容易使用,并且在创建时FromXmlString它是类的一部分,因此不需要辅助方法,也就是说,如果性能对您的项目意味着很多,您需要进行性能测试来比较结果。RSARSA.Create()

最后我提供了一个如何存储和加载密钥的简单示例:

public static void Main(string[] args)
{
    var rsa = RSA.Create();
    rsa.KeySize = 2048;

    // public key for decrypting
    var privateKey = rsa.ToXmlString(true);
    SaveKey(@"privateKey", privateKey);

    // public key for encrypting 
    var publicKey = rsa.ToXmlString(false);
    SaveKey(@"publicKey", publicKey);

    // initialize the private for use on another instance
    var rsaAnotherPlace = RSA.Create();
    rsaAnotherPlace.KeySize = 2048;
    rsaAnotherPlace.FromXmlString(LoadKey(@"privateKey"));
}

// store my keys
public static void SaveKey(string filename, string content)
{
    var bytes = Encoding.ASCII.GetBytes(content);
    using var fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
    fs.Write(bytes, 0, bytes.Length);
}

// load key
public static string LoadKey(string filename)
{
    var bytes = File.ReadAllBytes(filename);
    return Encoding.ASCII.GetString(bytes);
}
Run Code Online (Sandbox Code Playgroud)

我已经在 Windows 和 Linux 操作系统上测试了该解决方案,并且它通过了 GitHub actions 上的 macOS 测试,但我尚未在 macOS 上进行测试。

免责声明:是我正在开发的开源库。