1

This answer nicely explains how to create a new public/private key pair in .NET:

public static void AssignNewKey(){
    RSA rsa = new RSACryptoServiceProvider(2048); // Generate a new 2048 bit RSA key

    string publicPrivateKeyXML = rsa.ToXmlString(true);
    string publicOnlyKeyXML = rsa.ToXmlString(false);
    // do stuff with keys...
}

However, the "Remarks" section in the documentation of RSACryptoServiceProvider(Int32) says (emphasis mine):

Remarks

If no default key is found, a new key is created. [...]

What is this "default key" and how can I make sure that the RSACryptoServiceProvider constructor does not return that "default key" but a new key?

Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • I would check the store before and after to ensure the behaviour, but got no clue on the remarks. Googling a bit looks like the default key is used [if installed/configured](https://superuser.com/questions/263405/how-do-we-specify-an-ssh-default-identity) – Cleptus Sep 18 '18 at 09:49
  • Looking at the [source code](https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/utils.cs,462), unless you explicitly state that you want to use it, it will create ephemeral key – Hasan Emrah Süngü Sep 18 '18 at 09:57
  • 2
    FWIW, you should avoid using RSACryptoServiceProvider. Use RSA.Create()/RSA.Create(int) when you can, or RSACng if you have to do something fancy on Windows. – bartonjs Sep 18 '18 at 14:46
  • @bartonjs: Then why does [the documentation](https://learn.microsoft.com/en-us/dotnet/standard/security/cryptographic-signatures) tell me otherwise? (This is a serious question, not a rhetorical one.) – Heinzi Sep 18 '18 at 18:09
  • @Heinzi Tracing that documentation backwards it was [written in 2006](https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/6yxzeb7e(v=vs.85)) (or earlier). RSACryptoServiceProvider was required until .NET 4.6 (when the RSA base class was fixed to be able to be used without further casting). There are a lot of docs, and that hasn't gotten cleaned up yet. – bartonjs Sep 18 '18 at 18:15
  • Slightly off-topic, but what are you trying to do that you don't need a signed public-key certificate for the new key pair? It seems like you're either deploying a CA infrastructure to make certs on the fly, or you're opening the door to MitM. Either should be considered carefully in light of the end-use. (Or an explicitly anonymous protocol, I suppose) – lockcmpxchg8b Sep 20 '18 at 11:04
  • @bartonjs: Makes sense, thanks. – Heinzi Sep 20 '18 at 11:16
  • @lockcmpxchg8b: I am implementing a software licensing system: The private key will be kept secret and used to sign licenses, the public key will be hard-coded in our software and will be used to verify the license. For that, I need a public/private key pair. – Heinzi Sep 20 '18 at 11:22
  • Ah. So you're really just looking for a single long-lived key-pair in a form easily usable from .NET. Depending on the stakes, you might want to look at "application hardening" to make sure your licensing system stays in place and in-tact. If you're just looking to keep honest users honest, it's less important. – lockcmpxchg8b Sep 21 '18 at 00:18
  • @lockcmpxchg8b: Exactly. And since cryptography is easy to get wrong, I read the docs in detail and stop when I don't understand something, hence my question here. Re hardening: Yes, I understand that every locally installed application can be modified to remove any kind of copy protection. As you say, it's mostly about keeping honest users honest. – Heinzi Sep 21 '18 at 07:24

0 Answers0