使用签名中包含的密钥正确验证了签名,但该密钥不受信任
Posted
技术标签:
【中文标题】使用签名中包含的密钥正确验证了签名,但该密钥不受信任【英文标题】:The signature verified correctly with the key contained in the signature, but that key is not trusted 【发布时间】:2019-02-02 10:29:49 【问题描述】:我正在尝试将 SAML2 IdP Salesforce
配置为 IdentityServer3 中的外部提供程序。我正在使用SustainSys/Saml2 库。因此,出于测试目的,我下载了SampleIdentityServer3。并如下配置 SAML2 IdP
private void ConfigureSaml2(IAppBuilder app, string signInAsType)
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
var options = new Saml2AuthenticationOptions(false)
SPOptions = new SPOptions
EntityId = new EntityId("http://localhost:4589/IdSrv3/Saml2"),
MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
,
SignInAsAuthenticationType = signInAsType,
Caption = "SAML2p",
;
UseIdSrv3LogoutOnFederatedLogout(app, options);
options.SPOptions.ServiceCertificates.Add(new X509Certificate2(
AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/Sustainsys.Saml2.Tests.pfx"));
var idp = new IdentityProvider(
new EntityId("https://XXXXXX-dev-ed.my.salesforce.com"),
options.SPOptions)
MetadataLocation = "https://XXXXXX-dev-ed.my.salesforce.com/.well-known/samlidp.xml",
LoadMetadata = true,
;
options.IdentityProviders.Add(idp);
app.UseSaml2Authentication(options);
请注意,如果我没有将 MinIncomingSigningAlgorithm
设置为 sh1,那么 SustainSys 库会引发错误。
Sustainsys.Saml2.Exceptions.InvalidSignatureException:签名 算法http://www.w3.org/2000/09/xmldsig#rsa-sha1 弱于 接受的最低限度 http://www.w3.org/2001/04/xmldsig-more#rsa-sha256。如果你想 允许此签名算法,使用 minIncomingSigningAlgorithm 配置属性。
所以我将MinIncomingSigningAlgorithm
设置为"http://www.w3.org/2000/09/xmldsig#rsa-sha1"
以消除错误。
然后我得到不同的错误
Sustainsys.Saml2.Exceptions.InvalidSignatureException:签名 使用签名中包含的密钥正确验证,但是 密钥不受信任。
基于问题#493#735,元数据中的证书必须与 SAML2 响应中的证书匹配。
在元数据中证书是(注意开始和结束值)
<ds:X509Data>
<ds:X509Certificate>
MIIGk... removed from brevity....tmv6J1g==
</ds:X509Certificate>
</ds:X509Data>
但在 SAML2 响应中(由 SustainSys 库记录的响应)
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:4589/IdSrv3/Saml2/Acs" ID="_19fd2d8d9aab0401f56fXXXXXXXXX" InResponseTo="id473a52c49f194bXXXXXXXXX" IssueInstant="2018-08-27T20:10:04.296Z" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://XXXXXXX-dev-ed.my.salesforce.com</saml:Issuer>
<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="#_19fd2d8d9aab0401f56f642dXXXXXXXXXXXXX">
<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#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml samlp" /></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>fQiiyd0T57Ztr5BAfMFe9MTrhY0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
B6hndlsBgY45J+hm8My2gPVo....removed for brevity....YT88ajt7jQ==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIENz... remove for brevity....y2Ul24Jyc4V/jJN
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" />
</samlp:Status>
</samlp:Response>
查看元数据和 SAML2 响应中的 X509Certificate
值,它们不匹配。
问题
SAML2 响应中的 X509Certificate
值是否应该与元数据中的 X509Certificate
值匹配?如果是,为什么 SustainSys 库不能始终使用来自 SAML2 响应的 X509Certificate
值?
更新
只是为了看看匹配这些值是否有效,我将 SAML2 响应中的证书值保存到单独的 .cer
文件中。然后在 KeyInfoSerializer.cs 文件中我更新了ReadX509Certificate
方法(这是从元数据加载证书的方法)
private static SecurityKeyIdentifierClause ReadX509Certificate(XmlReader reader)
reader.ReadStartElement("X509Certificate", SignedXml.XmlDsigNamespaceUrl);
((XmlDictionaryReader)reader).ReadContentAsString();
var cer = new X509Certificate2(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/salesforcepublickey.cer");
var clause = new X509RawDataKeyIdentifierClause(cer);
reader.ReadEndElement();
return clause;
但是,它仍然会抛出错误The signature verified correctly with the key contained in the signature, but that key is not trusted.
【问题讨论】:
【参考方案1】:找到了。
这是 Salesforce 方面的问题。在 Saleforce 中,当我检查日志 Identity->Identity Provider Event Log
时,我看到错误 Error: User does not have access to this service provider
为此,未授予用户权限。即使用户是系统管理员,默认情况下也不会授予对 Connected App 的访问权限。要授予权限,请转到“管理用户-> 用户”并单击您正在测试的用户的编辑。单击配置文件名称链接。例如系统管理员。这需要配置文件页面。您可以在下方滚动到“连接的应用程序访问”,您会看到未授予访问权限。通过单击页面顶部的编辑配置文件授予访问权限。
【讨论】:
【参考方案2】:与这个无关,但是当我们在谷歌上搜索错误时,这个问题首先出现,所以在这里发布解决方案。我们在我们的 ASP.net 应用程序中集成了来自第三方提供商的 kentor auth 服务库,但由于上述错误而失败。
问题在于 IIS 不知何故无法访问证书存储。
我们为我们的网站在Application Pool
上启用了loadUserProfile
设置,它能够完美运行。我们在 Windows Server 2016 上应用了这个。
【讨论】:
以上是关于使用签名中包含的密钥正确验证了签名,但该密钥不受信任的主要内容,如果未能解决你的问题,请参考以下文章
Facebook:获取会话密钥时获取不正确的签名 (104)
您的 Android App Bundle 使用错误的密钥进行签名。确保您的 app bundle 使用正确的签名密钥进行签名,然后重试
您的 Android App Bundle 使用错误的密钥进行签名。确保您的 App Bundle 使用正确的签名密钥进行签名,然后重试:SHA1:
JwtSecurityTokenHandler ValidateToken:“签名验证失败。没有提供安全密钥来验证签名”