There is an implementation of RSA in C# .net,
That depends on what you mean by "implementation".
In .NET Framework there are two built-in classes which provide RSA functionality:
System.Security.Cryptography.RSACryptoServiceProvider
(mscorlib.dll)
System.Security.Cryptography.RSACng
(System.Core.dll)
In .NET Core there are 3.5 classes:
System.Security.Cryptography.RSACryptoServiceProvider
(System.Security.Cryptography.Csp.dll, some functionality Windows-only)
System.Security.Cryptography.RSACng
(System.Security.Cryptography.Cng.dll, Windows-only)
System.Security.Cryptography.RSAOpenSsl
(System.Security.Cryptography.OpenSsl.dll, non-Windows-only, requires OpenSsl 1.0.x on the system)
- The opaque type returned by
System.Security.Cryptography.RSA.Create()
(System.Security.Cryptography.Algorithms.dll)
None of those actually "implement" RSA, in that none of them really understand modulus, exponent, or CRT.
What value of $e$ they are choosen?
All of the inbox providers use F4 / 65537 / 0x010001 as the value for the public exponent with their default options.
I want to know what is the algorithm that they use to generate prime $p$ and $q$
That's up to the underlying library. In some cases, that's up to an underlying library for the underlying library.
RSACryptoServiceProvider (.NET Framework, .NET Core on Windows)
The key is created with CryptGenKey
.
Unless configured differently with a CspParameters
value in the constructor(s) which accept(s) one the type uses PROV_RSA_AES
with the default provider for that ProvType (MS_ENH_RSA_AES_PROV
/ "Microsoft AES Cryptographic Provider") and a key in the AT_EXCHANGE slot.
RSACryptoServiceProvider (.NET Core on non-Windows)
Skip ahead to RSA.Create(), this is just a compatibility type on non-Windows systems.
RSACng (.NET Framework, .NET Core on Windows)
The key is created with NCryptCreatePersistedKey
using a null
name (making it an ephemeral key) and the Microsoft Software Key Storage Provider
provider.
To create keys using other providers someone can call a CngKey.Create
overload and pass the pre-created key to new RSACng(CngKey)
.
RSAOpenSsl (.NET Core, non-Windows)
Keys are created using RSA_generate_key_ex
with a fixed $e$ = $65537$, and an RSA*
created with RSA_new
(the default engine).
RSA.Create() (.NET Core)
On .NET Core an opaque type is used for platform-independent RSA functionality. On Windows it's functionally equivalent to using RSACng
. On Linux (and any other *NIX other than macOS (or including macOS for the 1.0 or 1.1 releases)) it's functionally equivalent to using RSAOpenSsl
.
Starting with .NET Core 2.0 the macOS version is powered by a non-public type which creates the key using SecKeyGeneratePair
.
Completing the matrix
RSAOpenSsl
doesn't exist at all on .NET Framework, and throws PlatformNotSupportedException
on .NET Core for Windows. RSACng
throws PlatformNotSupportedException
on .NET Core for systems-other-than-Windows.
On .NET Framework RSA.Create()
emits an instance of RSACryptoServiceProvider
, unless configured differently via CryptoConfig
.
Other types
RSA is an open type, so anyone is free to write an RSA provider for .NET. This post contains all of the types that ship as part of .NET (Framework or Core) and provide RSA functionality... for any other types you'd need to track down their owners.
So, I know that doesn't really answer your question; but it does give you places you can go to further hunt things down if you want to know the answers.
The proof of these statements for .NET Core can be found at https://github.com/dotnet/corefx/. RSACng on .NET Framework at http://referencesource.microsoft.com/, and for RSACryptoServiceProvider on .NET Framework a combination of referencesource and a debugger (the actual call to CryptGenKey lives within clr.dll, which is not published on referencesource).
Oh, and Mono and Xamarin are probably doing something completely different.