Ответ 1
У меня была такая же проблема сегодня. Оказалось, что сертификат подписи WIF был создан с использованием CSP без поддержки SHA256 (подробнее).
Я просмотрел исходный код System.IdentityModel
и обнаружил, что он содержит специальную обработку для этого случая. Когда у вас есть соответствующий алгоритм, зарегистрированный глобально, WIF использует его вместо своей внутренней реализации, а класс RSAPKCS1SHA256SignatureDescription
не включает эту специальную обработку.
Итак, я сделал свою собственную реализацию SignatureDescription
, которая воссоздает RSACryptoServiceProvider
с параметрами по умолчанию, включая поддержку SHA256.
/// <summary>
/// Represents the sha256RSA signature algorithm.
/// </summary>
public sealed class RsaPkcs1Sha256SignatureDescription : SignatureDescription
{
/// <summary>
/// This type of CSP has SHA256 support
/// </summary>
private const int PROV_RSA_AES = 24;
public RsaPkcs1Sha256SignatureDescription()
{
KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
DigestAlgorithm = typeof(SHA256Cng).FullName;
FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
}
/// <summary>
/// Adds support for sha256RSA XML signatures.
/// </summary>
public static void RegisterForSignedXml()
{
CryptoConfig.AddAlgorithm(
typeof (RsaPkcs1Sha256SignatureDescription),
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
if (key == null) throw new ArgumentNullException("key");
key = GetSha2CompatibleKey(key);
var signatureDeformatter = new RSAPKCS1SignatureDeformatter(key);
signatureDeformatter.SetHashAlgorithm("SHA256");
return signatureDeformatter;
}
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
if (key == null) throw new ArgumentNullException("key");
key = GetSha2CompatibleKey(key);
var signatureFormatter = new RSAPKCS1SignatureFormatter(key);
signatureFormatter.SetHashAlgorithm("SHA256");
return signatureFormatter;
}
// Some certificates are generated without SHA2 support, this method recreates the CSP for them.
// See /info/451752/can-rsacryptoserviceprovider-nets-rsa-use-sha256-for-encryption-not-signing-instead-of-sha1/1971807#1971807
// WIF handles this case internally if no sha256RSA support is installed globally.
private static AsymmetricAlgorithm GetSha2CompatibleKey(AsymmetricAlgorithm key)
{
var csp = key as RSACryptoServiceProvider;
if (csp == null || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_AES)
return key;
var newKey = new RSACryptoServiceProvider(new CspParameters(PROV_RSA_AES));
newKey.ImportParameters(csp.ExportParameters(true));
return newKey;
}
}