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