DSACryptoServiceProvider.ToXmlString создает исключение "указаны неверные флаги"

Я пытаюсь сгенерировать пару ключей с DSACryptoServiceProvider.

Вот код:

        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);

На dsa.ToXmlString(true); Я получаю следующее исключение: указаны неверные флаги. В чем дело?

3 ответа

Решение

Максимальное значение ключа составляет 1024, см. Эту статью: Свойство DSACryptoServiceProvider.KeySize

"Этот алгоритм поддерживает длину ключа от 512 бит до 1024 бит с шагом 64 бита".

Проблема 1: Вы должны требовать крипто-контейнер, который поддерживает DH.

Проблема 2: Размер ключа не должен превышать 1024 (Windows тупой).

    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);

Однако при тестировании этого вы обнаружите проблему 3:

Проблема 3: CreateEphemeralKey тихо игнорируется DSACryptoProvider.

Получите копию DSAManaged от Mono, если хотите, чтобы она работала.

Здесь есть пара проблем.

  1. (Источник "Invalid Flags") Вы запросили эфемерный ключ, но затем назвали его. Обозначение ключа помечает его как сохраненный; поэтому вы запросили постоянный эфемерный ключ, и система запуталась.
  2. DSACryptoServiceProvider не поддерживает обновления FIPS-186-3 для DSA. Вам нужно использовать DSA-1024 или обновить до.NET 4.6.2 и использовать DSACng, который поддерживает FIPS-186-3 (увеличенные размеры ключей и хеширование SHA-2 (SHA256, SHA384, SHA512)).
  3. По умолчанию CspParameters объект имеет ProviderType=24, что для RSA. Вам нужно использовать 13, который предназначен для DSA. Магические числа менее волшебны в wincrypt.h (PROV_RSA_AES=24, PROV_DSS_DH=13).
  4. Если вам нужен кратковременный DSACryptoServiceProvider, самый простой способ - не указывать объект CspParameters и позволить ему использовать значение по умолчанию.

Любая из этих работ:

{
    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);
}
Другие вопросы по тегам