SSO SAML的签名XML签名validation(使用sha256)

在Windows 2003服务器上使用VS 2008和.Net Framework 3.5。

为了安全起见,我们使用SAML实施了SSO。 我们在服务提供商端工作,我们validation从客户端系统生成的签名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,我也检查并试过这个 。

我也在尝试使用RSAPKCS1SignatureDeformatter的VerifySignature方法。 但不确定要传递的两个参数是什么。

Dotnet 4.6.2+内置了更新的sha哈希。对于dotnet 4 +,要访问rsa-sha512,rsa-sha384和rsa-sha256,你应该在某个地方包含这个代码。

 /// Declare the signature type for rsa-sha512 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; } } /// Declare the signature type for rsa-sha384 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; } } /// Declare the signature type for rsa-sha256 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; } } 

然后,您应该通过调用这样的代码来激活这些sig描述。 您只需要调用一次,因此如果您愿意,可以从静态构造函数中调用它。

  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"); 

提示微软的Carlos Lopez和BitSchupster以及Andrew的SO。

对于.net 4及更早版本,我发现从http://clrsecurity.codeplex.com/添加Security.Cryptography后,以下工作正常。

(注意X509CertificateFinder是我自己的,通过指纹查找证书存储区中的签名证书)

  ///  /// Validate an XmlDocuments signature ///  ///  The saml response with the signature elemenet to validate  ///  True if signature can be validated with certificate  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); } 

这符合“简单”但可能不是“解决方案”的条件:)对于我们遇到过的少数客户,我们已要求他们使用SHA-1更改其IdP以进行签名。 他们能够改变它,当他们做到这一点时。

不是技术解决方案,但它在“现场”工作,所以我想我会提到它。

只需将其更新到.NET framework 4.6.01590或更高版本,它将支持SHA-512而无需更改任何代码。