0

I'm trying to generate a key pair with DSACryptoServiceProvider.

Here's the code:

        var cspParameters = new CspParameters();
        cspParameters.Flags = CspProviderFlags.CreateEphemeralKey;
        cspParameters.KeyContainerName = Guid.NewGuid().ToString();

        DSA dsa = new DSACryptoServiceProvider(2048, cspParameters); // Generate a new 2048 bit RSA key

        string publicPrivateKeyXML = dsa.ToXmlString(true);
        string publicOnlyKeyXML = dsa.ToXmlString(false);

On dsa.ToXmlString(true); I'm getting following exception: Invalid flags specified. What's wrong?

Arsen Zahray
  • 24,367
  • 48
  • 131
  • 224

3 Answers3

0

The maximum keysize property is 1024, see this article: DSACryptoServiceProvider.KeySize Property

"This algorithm supports key lengths from 512 bits to 1024 bits in increments of 64 bits."

David Martin
  • 11,764
  • 1
  • 61
  • 74
  • Wrong answer. Look you're right abut OP using too large of size but change size to 1024 and it still goes splat. – Joshua Apr 19 '16 at 16:25
0

Problem 1: You must demand a crypto container that supports DH.

Problem 2: Key size must not be large than 1024 (Windows is dumb).

    var cspParameters = new CspParameters(13); // 13 = PROV_DSS_DH which is not exported
    cspParameters.Flags = CspProviderFlags.CreateEphemeralKey;

    DSA dsa = new DSACryptoServiceProvider(1024, cspParameters); // Generate a new 2048 bit RSA key

    string publicPrivateKeyXML = dsa.ToXmlString(true);
    string publicOnlyKeyXML = dsa.ToXmlString(false);

Howevre on testing this you will discover problem 3:

Problem 3: CreateEphemeralKey is quietly ignored by DSACryptoProvider.

Go get a copy of DSAManaged from Mono if you want one that works.

Joshua
  • 40,822
  • 8
  • 72
  • 132
0

There are a couple of problems here.

  1. (The source of "Invalid Flags") You have requested an ephemeral key, but then named it. Naming a key marks it as persisted; so you asked for a persisted ephemeral key, and the system is confused.
  2. DSACryptoServiceProvider does not support the FIPS-186-3 updates to DSA. You need to use DSA-1024, or upgrade to .NET 4.6.2 and use DSACng, which does support FIPS-186-3 (increased key sizes, and SHA-2 (SHA256, SHA384, SHA512) hashing).
  3. The default CspParameters object has ProviderType=24, which is for RSA. You need to use 13, which is for DSA. The magic numbers are less magic in wincrypt.h (PROV_RSA_AES=24, PROV_DSS_DH=13).
  4. If you want an ephemeral DSACryptoServiceProvider, the easiest way is to not specify the CspParameters object, and let it use the default.

Any of these work:

{
    const int PROV_DSS_DH = 13;
    var cspParameters = new CspParameters(PROV_DSS_DH);
    DSA dsa = new DSACryptoServiceProvider(1024, cspParameters);

    string publicPrivateKeyXML = dsa.ToXmlString(true);
    string publicOnlyKeyXML = dsa.ToXmlString(false);
}

{
    const int PROV_DSS_DH = 13;
    var cspParameters = new CspParameters(PROV_DSS_DH);
    cspParameters.Flags = CspProviderFlags.CreateEphemeralKey;

    DSA dsa = new DSACryptoServiceProvider(1024, cspParameters);

    string publicPrivateKeyXML = dsa.ToXmlString(true);
    string publicOnlyKeyXML = dsa.ToXmlString(false);
}

{
    DSA dsa = new DSACryptoServiceProvider(1024);

    string publicPrivateKeyXML = dsa.ToXmlString(true);
    string publicOnlyKeyXML = dsa.ToXmlString(false);
}
bartonjs
  • 30,352
  • 2
  • 71
  • 111