在 .NET 核心中实现 RSA

implement RSA in .NET core

我正在尝试使用 RSA 加密和解密一些数据。我查过 RSA class 但我只看到摘要 class https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa(v=vs.110).aspx

我读到 DNX5 中的 RSA class 与 .net 4.6.1 中的不同,是否与我看到的不同?如果是这样,我在哪里可以找到使用该文档的文档?似乎 RSACryptoServiceProvider 在 .net 核心中不起作用,我只能访问 RSA 摘要 class。

您需要改用 dotnetcore 库。将 System.Security.Cryptography.Algorithms Nuget 包添加到您的项目中。您可以在这里找到它:System.Security.Cryptography.Algorithms

它为您的项目提供所有常用算法。

这是您将用于 Encrypt() 和 Decrypt() 方法的 RSACryptoServiceProvider class

您应该尽可能避免使用 RSACryptoServiceProvider。它只适用于 Windows(而且它是 Windows 上不太好的 RSA 实现)。坚持 RSA 基础 class,并通过 RSA.Create()

创建新实例

临时密钥(创建)

.NET 核心

using (RSA rsa = RSA.Create())
{
    rsa.KeySize = desiredKeySizeInBits;

    // when the key next gets used it will be created at that keysize.
    DoStuffWithThePrivateKey(rsa);
}

.NET 框架

不幸的是,.NET Framework 上 RSA.Create() 的默认设置是 RSACryptoServiceProvider,它不符合 set_KeySize。因此,如果您需要临时密钥,则需要在 .NET Framework 和 .NET Core 上使用不同的代码:

using (RSA rsa = new RSACng())
{
    rsa.KeySize = desiredKeySizeInBits;

    DoStuffWithThePrivateKey(rsa);
}

或者,如果您需要支持早于 4.6(其中不存在 RSACng)/4.6.2(其中大多数 .NET Framework 可以愉快地使用 RSACng 对象而不是 RSACryptoServiceProvider 对象)的版本,您可以继续使用旧的实现:

using (RSA rsa = new RSACryptoServiceProvider(desiredKeySizeInBits))
{
    // Since before net46 the Encrypt/Decrypt, SignData/VerifyData, SignHash/VerifyHash
    // methods were not defined at the RSA base class, you might need to keep this strongly
    // typed as RSACryptoServiceProvider.
    DoStuffWithThePrivateKey(rsa);
}

临时密钥(导入)

尽管 RSACng 通常比 RSACryptoServiceProvider 更容易使用,但 RSACryptoServiceProvider 在这种情况下应该可以正常工作,因此 RSA.Create() 在所有平台上都很好:

using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(rsaParameters);

    DoStuffWithWhateverKindOfKeyYouImported(rsa);
}

来自证书:

.NET Core 1.0+, .NET Framework 4.6+

using (RSA rsa = cert.GetRSAPublicKey())
{
    DoStuffWithThePublicKey(rsa);
}

using (RSA rsa = cert.GetRSAPrivateKey())
{
    DoStuffWithThePrivateKey(rsa);
}

.NET 框架 < 4.6

// Do NOT put this in a using block, since the object is shared by all callers:
RSA rsaPrivate = (RSA)cert.PrivateKey;
DoStuffWithThePrivateKey(rsaPrivate);

// Do NOT put this in a using block, since the object is shared by all callers:
RSA rsaPublicOnly = (RSA)cert.PublicKey.Key;
DoStuffWithThePublicKey(rsaPublic);

使用 Named/Persisted 键 (Windows-only)

我打算包括一些关于 RSACryptoServiceProvider (WinXP+/CAPI) 和 RSACng (Win7+/CNG) creating/opening 命名键的示例,但这在 .NET 中不是很常见的场景;而且它当然不可移植(对其他 OSes 的可移植性是 .NET Core 更有说服力的论点之一)。

引用事物。

对于 .NET Core 1.0 和 1.1,您可以从 System.Security.Cryptography.Algorithms 包访问 RSA 基础 class。在 .NET Core 2.0 中,它将包含在 netstandard 包参考中。

如果您需要与OS进行复杂的互操作,您可以参考System.Security.Cryptography.Cng(Windows CNG),System.Security.Cryptography.Csp (Windows CAPI/CryptoServiceProvider) 或 System.Security.Cryptography.OpenSsl (Linux OpenSSL, macOS OpenSSL) 并获得 interop-enabled classes(RSACng、RSACryptoServiceProvider、RSAOpenSsl)。但是,真的,你不应该那样做。

RSA.Create() return是什么?

  • .NET Framework:RSACryptoServiceProvider,除非由 CryptoConfig 更改。
  • .NET Core (Windows): 私有 class 通过 CNG 实现 RSA,你不能将它转换为任何更具体的类型。
  • .NET Core (Linux): 通过 OpenSSL 实现 RSA 的私有 class,你不能将它转换为任何更具体的类型。
  • .NET Core (macOS):一个私有的 class,它通过 OpenSSL 实现 RSA,你不能将它转换为任何更具体的类型。 (这应该通过 .NET Core 的下一版本中的 SecureTransforms 实现)