2013-05-24 3 views
6

Использование VS 2008 с .Net Framework 3.5 на сервере Windows 2003.Подписанная проверка подписи XML для SSO SAML (с использованием sha256)

Мы внедрили SSO с SAML для обеспечения безопасности. Мы работаем на стороне поставщика услуг, где мы проверяем токены Signed XML SAML Assertuib, созданные из системы клиента. В настоящее время все подписанные документы, с которыми мы сталкивались, использовали Алгоритм подписи «rsa-sha1», но теперь у нас есть новый клиент, который отправляет файл с алгоритмом подписи как «rsa-sha256», и вот проблема началась.

public static string VerifySignature() 
{ 
    if (m_xmlDoc == null) 
     return "Could not load XMLDocument "; 

    try 
    { 
     XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable()); 
     nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl); 
     XmlElement sigElt = (XmlElement)m_xmlDoc.SelectSingleNode(
      "//dsig:Signature", nsm); 

     // Load the signature for verification 
     SignedXml sig = new SignedXml(m_xmlDoc); 
     sig.LoadXml(sigElt); 

     if (!sig.CheckSignature()) 
      return "Invalid Signature"; 
    } 
    catch (Exception ex) 
    { 
     return ex.Message; 
    } 
    return string.Empty; 
} 

Теперь, когда я пытаюсь тот же код для этого нового клиента (с подписью алгоритма RSA-sha256h) - это не работает, и я получаю сообщение об ошибке «SignatureDescription не может быть создан для алгоритма подписи в комплект поставки. "

Пройдя через многие блоги и статьи за последние 2-3 дня, я узнал, что SignedXml не поддерживает sha256. Хорошо. Но что дальше. Где-то упоминалось, что использование WIF, я также проверил &, пробовал this.

Я также пытаюсь использовать метод VerifySignature RSAPKCS1SignatureDeformatter. Но не совсем уверен, какие два параметра должны быть переданы.

+0

У меня создалось впечатление, что алгоритм шифрования поддерживается, поскольку он поддерживает объект X509Certificate2. Метод sig.CheckSignature (...) имеет перегрузку, которая принимает 2 параметра: X509Certificate2 и bool. Вы пробовали использовать его и передали в cert и true? –

ответ

2

Это относится к «простому», но, возможно, не «решению» :). Для немногих клиентов, с которыми мы столкнулись, мы попросили их изменить их IdP на подписание с использованием SHA-1. Они могут изменить его, и когда они это делают, это работает.

Не техническое решение, но оно работает «в поле», поэтому я подумал, что упомянул об этом.

+0

У меня были клиенты, которые отказываются вносить это изменение, вздох. –

3

для .NET 4 и более ранних версий, я обнаружил, что следующие работы, как только вы добавить Security.Cryptography из http://clrsecurity.codeplex.com/

(Примечание X509CertificateFinder моя собственная, ищет сертификат подписи в хранилище сертификатов по отпечатку)

 /// <summary> 
     /// Validate an XmlDocuments signature 
     /// </summary> 
     /// <param name="xnlDoc"> The saml response with the signature elemenet to validate </param> 
     /// <returns> True if signature can be validated with certificate </returns> 
     public bool ValidateX509CertificateSignature(XmlDocument xnlDoc) 
     { 
      XmlNodeList XMLSignatures = xnlDoc.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#"); 

      // Checking If the Response or the Assertion has been signed once and only once. 
      if (XMLSignatures.Count != 1) return false; 

      var signedXmlDoc = new SignedXml(xnlDoc); 
      signedXmlDoc.LoadXml((XmlElement)XMLSignatures[0]); 

      var certFinder = new X509CertificateFinder(); 
      var foundCert = certFinder.GetSignatureCertificate(); 

      CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); 
      return signedXmlDoc.CheckSignature(foundCert,false); 
     } 
+2

Обратите внимание, что из .NET 4.5 вам не нужно устанавливать какие-либо сторонние библиотеки, в отличие от .net 4.0 и ранее. Вы можете просто добавить ссылку на System.Deployment и вызвать 'System.Security.Cryptography.CryptoConfig.AddAlgorithm (typeof (RSAPKCS1SHA256SignatureDescription), RsaSha256Namespace);' один раз в вашем процессе, после чего код в исходном вопросе будет работать с хэшами SHA256 , См. Также http://blogs.msdn.com/b/winsdk/archive/2015/11/15/using-sha256-with-signedxml.aspx – Rory

+0

'const string RsaSha256Namespace =" http://www.w3.org/ 2001/04/xmldsig-more # rsa-sha256 ";' – maddoxej

1

SHA-256 по умолчанию не включен в .NET 4.5. Поэтому, если вы используете .NET 3.5 или 4.0, вам нужно загрузить библиотеку безопасности с codeplex.com. Для получения дополнительной информации о валидации и создании сигнатуры SAML против алгоритма SHA-2 см. Эти вопросы http://www.componentpro.com/doc/saml/working-with-sha-256.htm и http://www.componentpro.com/doc/saml/Verifying-XML-Signatures.htm.

Вам понадобятся Ultimate SAML library for .NET.

8

Dotnet 4.6.2+ имеет новые sha хэшей, построенные. Для DotNet 4 +, чтобы получить доступ к RSA-SHA512, SHA384-ЗГА и RSA-SHA256, вы должны включите этот код где-нибудь.

/// <summary>Declare the signature type for rsa-sha512</summary> 
public class RsaPkCs1Sha512SignatureDescription : SignatureDescription 
{ 
    public RsaPkCs1Sha512SignatureDescription() 
    { 
     KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName; 
     DigestAlgorithm = typeof(SHA512CryptoServiceProvider).FullName; 
     FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName; 
     DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName; 
    } 

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA512"); 
     return sigProcessor; 
    } 

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = 
      (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA512"); 
     return sigProcessor; 
    } 
} 

/// <summary>Declare the signature type for rsa-sha384</summary> 
public class RsaPkCs1Sha384SignatureDescription : SignatureDescription { 
    public RsaPkCs1Sha384SignatureDescription() 
    { 
     KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName; 
     DigestAlgorithm = typeof(SHA384CryptoServiceProvider).FullName; 
     FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName; 
     DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName; 
    } 

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = (AsymmetricSignatureDeformatter) CryptoConfig.CreateFromName(DeformatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA384"); 
     return sigProcessor; 
    } 

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = 
      (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA384"); 
     return sigProcessor; 
    } 
} 

/// <summary>Declare the signature type for rsa-sha256</summary> 
public class RsaPkCs1Sha256SignatureDescription : SignatureDescription 
{ 
    public RsaPkCs1Sha256SignatureDescription() 
    { 
     KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName; 
     DigestAlgorithm = typeof(SHA256CryptoServiceProvider).FullName; 
     FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName; 
     DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName; 
    } 

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = 
      (AsymmetricSignatureDeformatter) CryptoConfig.CreateFromName(DeformatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA256"); 
     return sigProcessor; 
    } 

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) 
    { 
     var sigProcessor = 
      (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm); 
     sigProcessor.SetKey(key); 
     sigProcessor.SetHashAlgorithm("SHA256"); 
     return sigProcessor; 
    } 
} 

Затем вы должны активировать эти описания сигма, вызвав код следующим образом. Вам нужно только позвонить один раз, чтобы вы могли вызвать его из статического конструктора, если хотите.

CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha512SignatureDescription), 
     "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"); 
    CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha384SignatureDescription), 
     "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"); 
    CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription), 
     "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); 

Совет о»шляпа Microsoft's Carlos Lopez и BitSchupster и Andrew на SO.

+0

Это нашло работу .. Большое спасибо за то, что я много экономию. – amesh

+3

.... и ..... framework 4.6.2 заботится о эта проблема без необходимости использования дополнительного кода. –

+0

@OllieJones - вам известно, будет ли ваш код разбиваться на более поздний и последующий переход к цели 4.6.2? –

0

Просто обновите его до .NET framework 4.6.01590 или выше, и он поддержит SHA-512 без изменения кода.

Смежные вопросы