我的 SAML 重定向绑定签名有什么问题?
What's wrong with my signature for a SAML Redirect binding?
我正在尝试为重定向绑定创建一个 SAML AuthnRequest。
这是我的(匿名的)AuthRequest:
<samlp:AuthnRequest AssertionConsumerServiceURL="https://tempuri.org/sp/AssertionConsumerService"
Destination="https://anothertempuri.org/broker/sso"
ID="a18471d18a93430a8b97b05989ae238f"
IssueInstant="2017-07-23T14:15:26Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Version="2.0"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">...</saml:Issuer>
</samlp:AuthnRequest>
我有一个 RelayState:
RelayState: 821eea8785134bbc8263be6838eda19d
而 SigAlg 是 http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
我放气,然后 base64 编码,然后 URL 对请求进行编码。 (压缩后的 base64 编码结果在 SAMLTool Decoder 处检出。)
用于创建签名的结果字符串如下所示:
SAMLRequest=fZL...5MP&RelayState=821eea8785134bbc8263be6838eda19d&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256
我尝试使用 openssl 创建签名:
openssl sha -sha256 -sign example.pem -out signed.sha256 theStringInAFile.txt
openssl base64 -in signed.sha256
并使用 C#
byte[] data = File.ReadAllBytes(FileToSign);
data = SignBytes(data);
X509Certificate2 certificate = new X509Certificate2(CertFile, Password);
using (RSA rsa = certificate.GetRSAPrivateKey())
{
data = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
signedData = Convert.ToBase64String(data, Base64FormattingOptions.None);
并且(也使用 c#):
var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
HashAlgorithm hashAlg = signatureDescription.CreateDigest();
hashAlg.ComputeHash(Encoding.UTF8.GetBytes(signString));
X509Certificate2 certificate = new X509Certificate2(CertFile, Password);
AsymmetricSignatureFormatter asymmetricSignatureFormatter = signatureDescription.CreateFormatter(certificate.GetRSAPrivateKey());
byte[] signatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg);
return Convert.ToBase64String(signatureValue);
所有这三种方法都会产生相同的 base64 编码字符串(openssl 结果中的换行符除外)。
不幸的是,当我尝试将其与经纪人一起使用时,他们说签名有问题,当我向 SAMLTool AuthnRequest signing tool 提供相同的信息时,我得到了不同的结果。
我做错了什么?
问题是需要签名的字符串在一个文本文件中,其中(as a rule)在每一行的末尾包含一个换行符。但是,应签名的字符串不包括换行符。
这意味着解决方案是 trim 字符串中的换行符,例如通过替换
byte[] data = File.ReadAllBytes(FileToSign);
来自第一个 C# 代码块
string signString = File.ReadAllText(FileToSign);
signString = signString.TrimEnd('\r', '\n');
byte[] data = Encoding.UTF8.GetBytes(signString);
我正在尝试为重定向绑定创建一个 SAML AuthnRequest。
这是我的(匿名的)AuthRequest:
<samlp:AuthnRequest AssertionConsumerServiceURL="https://tempuri.org/sp/AssertionConsumerService"
Destination="https://anothertempuri.org/broker/sso"
ID="a18471d18a93430a8b97b05989ae238f"
IssueInstant="2017-07-23T14:15:26Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Version="2.0"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">...</saml:Issuer>
</samlp:AuthnRequest>
我有一个 RelayState:
RelayState: 821eea8785134bbc8263be6838eda19d
而 SigAlg 是 http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
我放气,然后 base64 编码,然后 URL 对请求进行编码。 (压缩后的 base64 编码结果在 SAMLTool Decoder 处检出。)
用于创建签名的结果字符串如下所示:
SAMLRequest=fZL...5MP&RelayState=821eea8785134bbc8263be6838eda19d&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256
我尝试使用 openssl 创建签名:
openssl sha -sha256 -sign example.pem -out signed.sha256 theStringInAFile.txt
openssl base64 -in signed.sha256
并使用 C#
byte[] data = File.ReadAllBytes(FileToSign);
data = SignBytes(data);
X509Certificate2 certificate = new X509Certificate2(CertFile, Password);
using (RSA rsa = certificate.GetRSAPrivateKey())
{
data = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
signedData = Convert.ToBase64String(data, Base64FormattingOptions.None);
并且(也使用 c#):
var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
HashAlgorithm hashAlg = signatureDescription.CreateDigest();
hashAlg.ComputeHash(Encoding.UTF8.GetBytes(signString));
X509Certificate2 certificate = new X509Certificate2(CertFile, Password);
AsymmetricSignatureFormatter asymmetricSignatureFormatter = signatureDescription.CreateFormatter(certificate.GetRSAPrivateKey());
byte[] signatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg);
return Convert.ToBase64String(signatureValue);
所有这三种方法都会产生相同的 base64 编码字符串(openssl 结果中的换行符除外)。
不幸的是,当我尝试将其与经纪人一起使用时,他们说签名有问题,当我向 SAMLTool AuthnRequest signing tool 提供相同的信息时,我得到了不同的结果。
我做错了什么?
问题是需要签名的字符串在一个文本文件中,其中(as a rule)在每一行的末尾包含一个换行符。但是,应签名的字符串不包括换行符。
这意味着解决方案是 trim 字符串中的换行符,例如通过替换
byte[] data = File.ReadAllBytes(FileToSign);
来自第一个 C# 代码块
string signString = File.ReadAllText(FileToSign);
signString = signString.TrimEnd('\r', '\n');
byte[] data = Encoding.UTF8.GetBytes(signString);