我正在发送一个SIGNED使用 c# 和 asp.net 向 idp 发出 authnRequest。我的代码对 authnRequest 进行签名,但签名验证在 idp 处失败。
Details
我尝试了很多解决方案但没有成功。
这就是我正在遵循的准则所做的事情https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf:
-
STEPS
- 缩小身份验证请求,然后对其进行 Base64 编码,最后对其进行 Url 编码。我们称之为 AR
- 对 RelayState 进行 URL 编码。我们称之为RS
- Url 对签名算法字符串进行编码。我们就叫它SA吧
- 所以要签名的字符串现在变成了SAMLRequest=AR&RelayState=RS&SigAlg=SA
- 现在,我使用我们的私钥(服务提供商私钥)对我们在步骤 #4 中获得的字符串进行签名。
6.我得到的结果签名,我对其进行base 64编码,然后对其进行URL编码。因此我得到了一个base64和url编码的签名。我们就叫它SG吧
- 现在,我将在步骤#6 中获得的签名附加到步骤#4 中的查询字符串。所以最终的查询字符串变成SAMLRequest=AR&RelayState=RS&SigAlg=SA&Signature=SG
所有这些工作正常,但签名验证失败!
这是我的代码,与此处找到的代码类似https://github.com/Sustainsys/Saml2/blob/v0.21.2/Kentor.AuthServices/WebSSO/Saml2RedirectBinding.cs#L53-L68 https://github.com/Sustainsys/Saml2/blob/v0.21.2/Kentor.AuthServices/WebSSO/Saml2RedirectBinding.cs#L53-L68
protected void btnSendAuthRequest_Click(object sender, EventArgs e)
{
string authRequest = txtInput.Text;
//authRequest = authRequest.TrimEnd('\r', '\n');
authRequest = DeflateBase64UrlEncode(authRequest);
string spPrivateKey= txtKey.Text;
string relayState = HttpUtility.UrlEncode("https://example.com/pages/home.aspx");
string qs = "SAMLRequest=" + authRequest + "&RelayState=" + relayState;
qs = AddSignature(qs, spPrivateKey);
txtOutput.Text = qs;
}
public string AddSignature(string queryString, string PrivateKeyNoHeaders)
{
RSACryptoServiceProvider tmpRsa = RSAKeyTests.RSAKeyUtils.DecodePrivateKeyInfo(Convert.FromBase64String(PrivateKeyNoHeaders));
string signingAlgorithmUrl = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
queryString += "&SigAlg=" + HttpUtility.UrlEncode(signingAlgorithmUrl);
var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName(signingAlgorithmUrl);
HashAlgorithm hashAlg = signatureDescription.CreateDigest();
hashAlg.ComputeHash(Encoding.UTF8.GetBytes(queryString));
AsymmetricSignatureFormatter asymmetricSignatureFormatter =
signatureDescription.CreateFormatter(
((RSACryptoServiceProvider)tmpRsa));
//.GetSha256EnabledRSACryptoServiceProvider());
// Is the signature failing because of above ?
byte[] signatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg);
queryString += "&Signature=" + HttpUtility.UrlEncode(Convert.ToBase64String(signatureValue));
return queryString;
}
private string DeflateBase64UrlEncode(string input)
{
var inputs = string.Format(input, Guid.NewGuid());
var bytes = Encoding.UTF8.GetBytes(inputs);
using (var output = new MemoryStream())
{
using (var zip = new DeflateStream(output, CompressionMode.Compress))
{
zip.Write(bytes, 0, bytes.Length);
}
var base64 = Convert.ToBase64String(output.ToArray());
return HttpUtility.UrlEncode(base64);
}
}
CryptoConfig.createFromName(...)
不知道 https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=netframework-4.8 about http://www.w3.org/2000/09/xmldsig#rsa-sha1
作为摘要+签名算法。如果CryptoConfig.createFromName()
不返回 null,无论注册什么算法http://www.w3.org/2000/09/xmldsig#rsa-sha1
可能不是 RSA-SHA1。这是一个显式的实现SignatureDescription
使用 RSA 和 SHA1:
public class RSASHA1SignatureDescription : SignatureDescription {
public RSASHA1SignatureDescription() {
KeyAlgorithm = "System.Security.Cryptography.RSA";
DigestAlgorithm = "System.Security.Cryptography.SHA1Cng";
FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
_hashAlgorithm = "SHA1";
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) {
AsymmetricSignatureDeformatter item = (AsymmetricSignatureDeformatter) CryptoConfig.CreateFromName(DeformatterAlgorithm);
item.setKey(key);
item.SetHashAlgorithm(_hashAlgorithm);
return item;
}
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) {
AsymmetricSignatureFormatter item = (AsymmetricSignatureFormatter) CryptoConfig.CreateFromName(FormatterAlgorithm);
item.setKey(key);
item.SetHashAlgorithm(_hashAlgorithm);
return item;
}
private string _hashAlgorithm;
}
另一种可能性是,您验证签名时不需要 rsa-sha1(许多身份提供商通过配置禁止 rsa-sha1)或者验证不正确。尝试使用真正的 IdP(例如 Okta 或 Salesforce)注册并在那里进行验证。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)