Неверный алгоритм при создании подписи rsa-sha512 - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь применить подпись rsa-sha512 к сообщению, используя сертификат на локальном жестком диске. Окончательные данные SignData вызывают криптографическое исключение «Указан неверный алгоритм». Однако, если я использую SignData на новом экземпляре RSACryptoServiceProvider (созданном путем импорта экспорта исходного RSACryptoServiceProvider), я не получаю это исключение. Есть ли какая-то причина, по которой оригинальная версия вызывает исключение? Поскольку «копия» явно отличается, я бы предпочел использовать оригинал.

Код C #, который я использую, выглядит следующим образом:

X509Certificate2 cert = new X509Certificate2("C:\\Certs\\" + certName + ".p12", certPassword, X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey;
UTF8Encoding ByteConverter = new UTF8Encoding();
byte[] unsignedBytes = ByteConverter.GetBytes(unsignedText);
byte[] signature;

//This raises an exception, "Invalid algorithm specified."
signature = csp.SignData(unsignedBytes, new SHA512CryptoServiceProvider());

//But if I make a copy of the RSACryptoServiceProvider, no exception is raised
RSACryptoServiceProvider cspCopy = new RSACryptoServiceProvider();
RSAParameters Key = csp.ExportParameters(true);
cspCopy.ImportParameters(Key);
signature = cspCopy.SignData(unsignedBytes, new SHA512CryptoServiceProvider());

1 Ответ

0 голосов
/ 30 апреля 2018

Цитировать себя из предыдущего ответа :

Программно-поддерживаемый RSACryptoServiceProvider способен выполнять подпись RSA только с использованием алгоритма дайджеста SHA-2, когда значение CSP ProviderType равно 24 (PROV_RSA_AES), а ProviderName - «Microsoft Enhanced RSA и AES Cryptographic Provider» (MS_ENH_RSA_AES_P). Аппаратное обеспечение может требовать или не требовать PROV_RSA_AES, зависит только от аппаратного обеспечения.

В этом случае PFX идентифицирует закрытый ключ, принадлежащий старому CSP (или, возможно, у него нет идентификатора CSP, а импорт PFX выбирает неправильные значения по умолчанию). Для программных ключей можно извлечь данные CspParameterInfo из ключа и повторно открыть их, используя ProviderType 24, что является одним из способов решения проблемы. Экспорт необработанных параметров RSA и импорт их в новый объект (по умолчанию это ProviderType 24) - более агрессивный обходной путь.

Лучший способ обойти эту проблему - отказаться от RSACryptoServiceProvider. Вместо использования cert.PrivateKey, используйте cert.GetRSAPrivateKey(), который почти всегда будет возвращать экземпляр RSACng, у которого нет этой проблемы (но не приводите его, если можете избежать этого (если ничего больше, всегда смотрите «почти») )).

byte[] signature;

using (RSA rsa = cert.GetRSAPrivateKey())
{
    signature = rsa.SignData(
        unsignedBytes,
        HashAlgorithmName.SHA512,
        RSASignaturePadding.Pkcs1);
}

Оператор using является правильным для GetRSAPrivateKey, поскольку он возвращает отдельный объект за вызов.

Для RSACng и GetRSAPrivateKey требуется .NET 4.6, но к этому моменту уже более двух лет (и за это время произошло 4 (с половиной) более новых выпусков), поэтому не должно вызывать у вас затруднения как зависимость.

...