2014-12-04 48 views
12

似乎SignedXml.CheckSignature只适用于使用SHA1签名的文档。如何使用SHA256检查签名XML文档的签名?

我试图this code通过添加算法SHA256,和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中指定算法?

+2

这是一个特定的.NET 4.5问题吗?我通常会更改标签,但给你的代表,我会等待一个答案。 (该死的,你是怎么得到这么多黄金的?) – leppie 2014-12-05 20:00:35

+0

是的。仅限于.Net 4.5版本。 – Homam 2015-06-12 15:25:54

回答

3

今天我有同样的问题。事实证明,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; 
    } 
} 
+0

它没有工作,它正在抛出一个加密异常'密钥在指定状态下无效.' – Homam 2015-06-03 07:43:58

相关问题