0

作为服务提供商,当尝试使用 SAML2 连接、使用 IdentityServer4 和 Sustainsys.Saml2.AspNetCore2 包连接到 IDP 时,我一直遇到运行时异常,并且没有真正的线索是否这是一个错误或如何解决它。据我所知,这是一个完全有效的加密算法,并且在检索 IDP 的 URL 的元数据时被接受为有效输入。不知道为什么它一直告诉我不是。客户端的元数据无法更改,并且

我确实成功连接到模拟的https://stupidp.sustainsys.com,使用

OutboundSigningAlgorithm = SignedXml.XmlDsigRSASHA1Url;

(但不确定这是否是有效的比较)。

SAML 元数据文件签名部分:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    <ds:Reference URI="#aselect-s.entree.kennisnet.nl">
      <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
      <ds:DigestValue>...</ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
<ds:SignatureValue>...

(查看完整文件https://hub-s.entree.kennisnet.nl/openaselect/profiles/saml2

和基本配置

 services.AddAuthentication()
   .AddSaml2("...", "...", options =>
     { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
       options.SignOutScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme;
       options.SPOptions.ModulePath = "/Saml2";
       options.SPOptions.EntityId = new EntityId("http://localhost:51827");   
       options.SPOptions.MetadataCacheDuration = new XsdDuration(hours: 1);
       options.SPOptions.OutboundSigningAlgorithm = SignedXml.XmlDsigRSASHA1Url;
       options.SPOptions.MinIncomingSigningAlgorithm = SignedXml.XmlDsigRSASHA1Url;
       options.IdentityProviders.Add(
         new IdentityProvider(
           new EntityId("..."), options.SPOptions)  
             {
               LoadMetadata = true,                                                       
               MetadataLocation = "..."                          
             });

       options.SPOptions.ServiceCertificates.Add(new X509Certificate2("....pfx")); 
       options.SPOptions.Organization = organisation;
       options.SPOptions.Contacts.Add(contact);
     });

当单击按钮连接到此 IDP 时,这一切都会导致以下堆栈跟踪。

System.Security.Cryptography.CryptographicException: Unknown crypto algorithm 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
   at Sustainsys.Saml2.Internal.CryptographyExtensions.CreateAlgorithmFromName(String name, Object[] args)
   at Sustainsys.Saml2.WebSso.Saml2RedirectBinding.AddSignature(String queryString, ISaml2Message message)
   at Sustainsys.Saml2.WebSso.Saml2RedirectBinding.Bind(ISaml2Message message, ILoggerAdapter logger)
   at Sustainsys.Saml2.WebSso.SignInCommand.InitiateLoginToIdp(IOptions options, IDictionary`2 relayData, Saml2Urls urls, IdentityProvider idp, Uri returnUrl)
   at Sustainsys.Saml2.WebSso.SignInCommand.Run(EntityId idpEntityId, String returnPath, HttpRequestData request, IOptions options, IDictionary`2 relayData)
   at Sustainsys.Saml2.AspNetCore2.Saml2Handler.ChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)

我做错了什么还是没有得到正确的支持?

为什么连接到存根 IDP 时它会起作用?

这是否从CryptographyExtensions.s_extraAlgorithms(参见开源代码)中丢失,因为它只显示列出的 3 种 RSA 类型,而代码中的其他列表通常将 SHA1 命名为第四个?

4

2 回答 2

0
  1. 即使您设置了 OutboundSigningAlgorithm,默认情况下,对 StubIdp 的出站请求也不会签名。如果 Idp 的元数据请求它(StubIdp 没有)或 AuthenticateRequestSigningBehavior 设置为 Always,则启用签名。如果将其更改为始终,即使使用 StubIdp,您也可能会收到错误消息。

  2. SHA1 算法正在逐步淘汰,因为其中发现了弱点。我的猜测是,在您的系统上 CryptoConfig.CreateFromName 不知道http://www.w3.org/2000/09/xmldsig#sha1名称。

但我不会花时间让 SHA1 工作。我会改用 SHA256,因为这被认为是安全的。

于 2019-09-06T11:05:10.537 回答
0

随着@identigral 的提示,发现只需再次添加加密算法就可以了:

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA1SignatureDescription), SignedXml.XmlDsigRSASHA1Url);

public class RSAPKCS1SHA1SignatureDescription : SignatureDescription
{
        private readonly string _hashAlgorithm;

        public RSAPKCS1SHA1SignatureDescription()
        {
            KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
            DigestAlgorithm = typeof(SHA1Managed).FullName;                
            FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
            DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
            _hashAlgorithm = "SHA1";
        }

        public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var deformatter = new RSAPKCS1SignatureDeformatter(key);
            deformatter.SetHashAlgorithm(_hashAlgorithm);
            return deformatter;
        }

        public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var formatter = new RSAPKCS1SignatureFormatter(key);
            formatter.SetHashAlgorithm(_hashAlgorithm);
            return formatter;
        }     
}

虽然被认为是一个不安全的协议,但这些都是给定的要求,而不是我的选择。也许未来对Sustainsys.Saml2包的补充是将此协议添加到未识别协议列表中,s_extraAlgorithms并确保一个简单的实现。但是对于这个hickup,一个很好的包就可以了。

于 2019-09-10T13:42:04.230 回答