bcgit / bc-csharp

BouncyCastle.NET Cryptography Library (Mirror)
https://www.bouncycastle.org/csharp
MIT License
1.67k stars 557 forks source link

DotNetUtilities class only works on Windows #160

Open johnhargrove opened 6 years ago

johnhargrove commented 6 years ago

Good evening,

I'm porting a .NET Framework library that uses BouncyCastle to .NET Standard, and I'm using the Portable.BouncyCastle nuget package for this. I'm running into an issue where our code relies on the DotNetUtilities.ToRSA() method. This method is available in the portable version, but it only works on Windows, due to relying on the key container functionality that only exists on Windows. This is the stacktrace on Linux:

 System.PlatformNotSupportedException: 'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
   at Org.BouncyCastle.Security.DotNetUtilities.CreateRSAProvider(RSAParameters rp) in D:\a\1\s\crypto\src\security\DotNetUtilities.cs:line 245
   at Org.BouncyCastle.Security.DotNetUtilities.ToRSA(RsaPrivateCrtKeyParameters privKey) in D:\a\1\s\crypto\src\security\DotNetUtilities.cs:line 169

So, the build works but it does not work at runtime, which is not desirable for a portable library.

Side question: I'm a bit confused why this function even uses the key container functionality? I was surprised to find that the keys were being persisted at all, given the function just setting up an RSACryptoServiceProvider. Of course, there could be valid reasons for this but I found it strange.

I think either this class should be removed from .NET Standard builds, or perhaps conditionally compiled to only expose APIs that can work cross-platform, as the conversion tools are quite useful.

Related issue: https://github.com/bcgit/bc-csharp/issues/113#issuecomment-435440214

jatmika-com commented 4 years ago

And finally today I bumped on this problem myself after publishing my projects into linux-based hosts. Isn't it resolved yet?

sipsorcery commented 4 years ago

+1.

This dotnet core issue also seems to indicate there is no need for the CspParameters to be used in this case (there doesn't seem to be any key persistence in the DotNetUtilities class that would necessitate the use of CspParameters).

kskalski commented 4 years ago

Indeed, doing

      var parms = DotNetUtilities.ToRSAParameters(ko.Private as RsaPrivateCrtKeyParameters);
      var rsa = RSA.Create();
      rsa.ImportParameters(parms);
      return rsa;

instead of

DotNetUtilities.ToRSA(ko.Private as RsaPrivateCrtKeyParameters)

fixes the issue on Linux, I guess this could be easily factored into the library

jatmika-com commented 4 years ago

Indeed, doing

      var parms = DotNetUtilities.ToRSAParameters(ko.Private as RsaPrivateCrtKeyParameters);
      var rsa = RSA.Create();
      rsa.ImportParameters(parms);
      return rsa;

instead of

DotNetUtilities.ToRSA(ko.Private as RsaPrivateCrtKeyParameters)

fixes the issue on Linux, I guess this could be easily factored into the library

wow, a great simple solution, will try it tomorrow in the office :D

kskalski commented 4 years ago

just note, that there is a problem on Windows with the above code (https://github.com/dotnet/runtime/issues/23749), right now I need to use this:

      if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
        return DotNetUtilities.ToRSA(ko.Private as RsaPrivateCrtKeyParameters);
      var parms = DotNetUtilities.ToRSAParameters(ko.Private as RsaPrivateCrtKeyParameters);
      var rsa = RSA.Create();
      rsa.ImportParameters(parms);
      return rsa;

which handles conversion well on both Windows and Linux

jinjupeng commented 3 years ago

Indeed, doing

      var parms = DotNetUtilities.ToRSAParameters(ko.Private as RsaPrivateCrtKeyParameters);
      var rsa = RSA.Create();
      rsa.ImportParameters(parms);
      return rsa;

instead of

DotNetUtilities.ToRSA(ko.Private as RsaPrivateCrtKeyParameters)

fixes the issue on Linux, I guess this could be easily factored into the library

Thanks,its resolve my question!