【发布时间】:2019-08-17 10:28:33
【问题描述】:
我正在使用 c# 和 asp.net 向 idp 发送 SIGNED authnRequest。我的代码对 authnRequest 进行了签名,但签名验证在 idp 处失败。
详情
我尝试了很多解决方案,但都是徒劳的。 这就是我按照https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf 设置的指导方针所做的事情:
-
步骤
- 对身份验证请求进行压缩,然后对其进行 base64 编码,最后进行 Url 编码。让我们称之为 AR
- URL 对 RelayState 进行编码。让我们称之为 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 的代码相似
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);
}
}
【问题讨论】:
标签: c# asp.net saml saml-2.0 sign