I'm trying to create a SAML AuthnRequest for the redirect binding.
This is my (anonymized) 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>
I have a RelayState:
RelayState: 821eea8785134bbc8263be6838eda19d
And the SigAlg is http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
I deflate, then base64-encode, then URL-encode the request. (The deflated, base64-encoded result checks out at the SAMLTool Decoder.)
The resulting string to be used for creating the signature then looks something like this:
SAMLRequest=fZL...5MP&RelayState=821eea8785134bbc8263be6838eda19d&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256
I tried creating the signature with openssl:
openssl sha -sha256 -sign example.pem -out signed.sha256 theStringInAFile.txt
openssl base64 -in signed.sha256
and with 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);
And (also with 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);
All three methods result in the same base64-encoded string (except for the newlines in the openssl result).
Unfortunately, when I try to use this with the broker, they say something is wrong with the signature, and when I feed the same info to the SAMLTool AuthnRequest signing tool I get a different result.
What am I doing wrong?
SAMLRequest=...&RelayState=...&SigAlg=...
as per the spec section 3.4.4.1, second item 3. – Miel