似乎SignedXml.CheckSignature只对使用SHA1的签名文档工作正常.
我通过添加算法SHA256尝试了this code,CheckSignature工作正常,但WIF类开始抛出以下异常:
System.Security.Cryptography.CryptographicException:指定的无效算法.在这个方法调用
System.IdentityModel.Services.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest
看来ProcessSignInRequest使用的算法SHA1在内部被覆盖:
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
我错过了什么?如何在CheckSignature中指定算法?
今天我也有同样的问题.原来,WIF签名证书是使用没有SHA256支持的CSP生成的(
more details).
我浏览了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 https://stackoverflow.com/a/11223454/280778 // 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; } }