Цитировать себя из предыдущего ответа :
Программно-поддерживаемый 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 (с половиной) более новых выпусков), поэтому не должно вызывать у вас затруднения как зависимость.