2013-05-24 47 views
6

Sử dụng VS 2008 với .Net Framework 3.5 trên máy chủ Windows 2003.Xác minh chữ ký XML đã ký cho SSO SAML (Sử dụng sha256)

Chúng tôi đã triển khai SSO với SAML để bảo mật. Chúng tôi làm việc tại nhà cung cấp dịch vụ kết thúc, nơi chúng tôi xác thực mã thông báo SAML Assertuib XML đã được tạo từ hệ thống của khách hàng. Hiện tại, bất kỳ tài liệu đã ký nào đều sử dụng Thuật toán Chữ ký "rsa-sha1", nhưng bây giờ chúng tôi có khách hàng mới gửi tệp với thuật toán chữ ký là "rsa-sha256" và đây là sự cố bắt đầu.

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; 
} 

Bây giờ, khi tôi cố gắng cùng mã cho khách hàng mới này (có chữ ký của thuật toán rsa-sha256h) - điều này không hoạt động và tôi nhận được lỗi "SignatureDescription không thể được tạo ra cho các thuật toán chữ ký cung cấp. "

Đi qua nhiều blog và bài viết trong 2-3 ngày qua, tôi đã biết rằng SignedXml không hỗ trợ sha256. Khỏe. Nhưng những gì tiếp theo. Một nơi nào đó đề cập rằng sử dụng WIF, tôi cũng đã kiểm tra & đã thử this.

Tôi cũng đang cố sử dụng phương pháp VerifySignature của RSAPKCS1SignatureDeformatter. Nhưng không thực sự chắc chắn hai thông số được thông qua là gì.

+0

Tôi đã ấn tượng rằng thuật toán mã hóa được hỗ trợ bởi vì nó hỗ trợ đối tượng X509Certificate2. Phương thức sig.CheckSignature (...) có quá tải cần 2 tham số, X509Certificate2 và bool. Bạn đã thử sử dụng nó và đi qua trong cert và sự thật? –

Trả lời

2

Điều này đủ điều kiện cho "đơn giản" nhưng có lẽ không phải "giải pháp" :) Đối với một số khách hàng mà chúng tôi đã gặp phải, chúng tôi đã yêu cầu họ thay đổi IdP của họ để ký bằng SHA-1. Họ có thể thay đổi nó, và khi họ làm việc đó.

Không phải giải pháp kỹ thuật, nhưng nó đã hoạt động 'trong lĩnh vực này' vì vậy tôi nghĩ tôi sẽ đề cập đến nó.

+0

Tôi đã có khách hàng từ chối thực hiện thay đổi đó, thở dài. –

3

Đối .net 4 trở về trước, tôi thấy rằng các công việc sau khi bạn thêm Security.Cryptography từ http://clrsecurity.codeplex.com/

(Lưu ý X509CertificateFinder là của riêng tôi, trông cấp Giấy chứng nhận chữ ký trong kho chứng chỉ bằng vân tay)

 /// <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

Lưu ý rằng từ .NET 4.5 bạn không cần phải cài đặt bất kỳ thư viện của bên thứ ba nào khác với trong .net 4.0 và phiên bản cũ hơn. Bạn chỉ có thể thêm một tham chiếu đến System.Deployment và gọi 'System.Security.Cryptography.CryptoConfig.AddAlgorithm (typeof (RSAPKCS1SHA256SignatureDescription), RsaSha256Namespace);' một lần trong quá trình của bạn, sau đó mã trong câu hỏi ban đầu sẽ làm việc với các băm SHA256 . Xem thêm 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 không được bật theo mặc định trong .NET 4.5. Vì vậy, nếu bạn sử dụng .NET 3.5 hoặc 4.0, bạn cần tải xuống thư viện bảo mật từ codeplex.com. Để biết thêm thông tin về xác thực và tạo chữ ký SAML đối với thuật toán SHA-2, vui lòng xem các chủ đề này http://www.componentpro.com/doc/saml/working-with-sha-256.htmhttp://www.componentpro.com/doc/saml/Verifying-XML-Signatures.htm.

Bạn sẽ cần Ultimate SAML library for .NET.

8

Dotnet 4.6.2+ có sha băm mới được xây dựng trong. Đối với DotNet 4 +, để có được quyền truy cập vào rsa-SHA512, rsa-sha384, và rsa-sha256, bạn nên bao gồm mã này ở đâu đó.

/// <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; 
    } 
} 

Sau đó, bạn nên kích hoạt các mô tả bằng cách gọi mã như thế này. Bạn chỉ cần gọi nó một lần, vì vậy bạn có thể gọi nó từ một nhà xây dựng tĩnh nếu bạn muốn.

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

Mẹo o' chiếc mũ để Microsoft's Carlos LopezBitSchupsterAndrew trên SO.

+0

Làm việc này .. Cảm ơn rất nhiều vì đã dành rất nhiều thời gian cho tôi .. – amesh

+3

.... và ..... framework 4.6.2 sẽ xử lý vấn đề này mà không cần thêm mã. –

+0

@OllieJones - bạn có biết rằng mã của bạn sẽ bị phá vỡ sau này và di chuyển tiếp theo để nhắm mục tiêu 4.6.2 không? –

0

Chỉ cần cập nhật nó lên .NET framework 4.6.01590 trở lên và nó sẽ hỗ trợ tối đa SHA-512 mà không cần bất kỳ thay đổi mã nào.

Các vấn đề liên quan