2014-12-04 92 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

相關問題