We develop SAML 2.0 SSO application and we experience an issue with logout request comming from https://login.microsoftonline.com/ In short - signature verification fails.
Below is a logout request live sample. It has no embedded signature but it uses DEFLATE encoding algorithm for signing RL parameter). Also you can find below the verification according to SAML 2.0 specifications with help of openssl application in Linux console which results in verification failure. Please help me to find a reason of failure.
SAMLRequest=jZJBa9wwEIX%2fitFdtmxL8lp4TReWgiFNIAk99BK01nhrsCVXI5P9%2bVG8LekWWnoTwzy9781Mg3qeFnXnzm4Nj%2fBjBQxJd9yTl7wfam4gp5IPOeW8rulO7Eq6q06yklr2FZQk%2bQoeR2f3pEgZSTrEFTqLQdsQS6wQlHFaiGcmFK%2bUqFJZlt9Icowuo9VhU34PYUGVZVF1BqqXBYPzkII5g4XLiunosnfKCEiSexce7IM%2fDAH8rYO8cbjMk0W1hduT1VvlNI6orJ4BVejV0%2bHLnYrMavEuuN5NpG02en%2bV%2flukEcG%2f05P2gx7T19Ea94qphZANHICbWlJT9ZxyHV8nCSWFQmpmKpkbprMmu3q2zX306I7JZ%2bdnHUf3N%2fM8zbfKaOiwtSqY9TgdjPGA%2bDP2f7PjrKdPv8%2b5ya4cbXM9i6f4aezsrIFL%2b9LHAKKO4wYuBOVFvAgtSka5qHl%2fyquyZqzZVvWH8lfx5sraNw%3d%3d&Signature=MQ07yezl943nmhHi4IIw30vhXj0jjo3XckRLSRRNVjs8QIA1rU%2fZPMYm7bB9yvlzcTIEtrpT%2bOoODQNrNZn7sRJZa7Akk%2fOy2SjrENbgYCBC1VnD8iFyxmVhbrSTYZIzkR6Bb%2fc5GlEHXLOWBaORuKtXByIOtVm3LdtM2hftPqzJa6AD44r2EjbG3J%2b2bPOfP%2f7i2wL4iYLx0wqrtqEnBADV5%2bawHuhZQkXYsQ8DnzSOSgCuEReSoYRZIg8DFbB6kKMVX8cx7eGgWyE%2fyX23zPhFa5FlHnIemyCiMMGtLpaAfQE1Dzki5%2bE29YLIZ8ROlU37%2b1EtKVYfFtGv1SV7Og%3d%3d&SigAlg=http%3a%2f%2fwww.w3.org%2f2001%2f04%2fxmldsig-more%23rsa-sha256
[root@edgenexus ~]# cat Azure.crt
subject=CN = Microsoft Azure Federated SSO Certificate
issuer=CN = Microsoft Azure Federated SSO Certificate
-----BEGIN CERTIFICATE-----
MIIC8DCCAdigAwIBAgIQGB9ocyPWQrdNsFEMayBqIzANBgkqhkiG9w0BAQsFADA0
MTIwMAYDVQQDEylNaWNyb3NvZnQgQXp1cmUgRmVkZXJhdGVkIFNTTyBDZXJ0aWZp
Y2F0ZTAeFw0yNDExMjIxMzEyNTVaFw0yNzExMjIxMzEyNTNaMDQxMjAwBgNVBAMT
KU1pY3Jvc29mdCBBenVyZSBGZWRlcmF0ZWQgU1NPIENlcnRpZmljYXRlMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp4iF0YcsKf2Hr/aaTfCBsXzBWfDW
wvgUeFYXYR/PJaiVpq63L5RWpDSsRFabsjqC2LiTp4mjlq13gQpnCig5I9MIbtTQ
bKUWZr3Giv/JPBorm1ptfSKcUWDNin0tWmiYQ1HdqicbhWapzE+8o+rZQTJR3JOG
2zDeBgJIjnV087GRQwHOB9FTotZZrG74BXuGFsRRj44DS4Bq6bglLrxMv0ckLsto
J6LJFexrESuPEQAkXtm/lbmgDHbvZcpAAER45JgKbOm9Od572FQ3ci5skPWwfpeC
uNBakk2fK5BN+nXOUr1M2O04Z1ekr3uVhddc1NislUrgNJJ+HDBNPbzIcQIDAQAB
MA0GCSqGSIb3DQEBCwUAA4IBAQANsp7PtaFy5jKQXMBRM9xDR4lz40bD/UpoeWgt
pSf/WgWjclHn/DN90iI3/QoaUy921Ujw0FfObAoGzTjrgQekc2XmNtyITTznAOsP
G7j+1gIUrqwov8Rt7yYpqE59ABosqrAMWAu5FCJ0o+tZ7mVSB/xSBME0EO7P78Qm
UQ+CcZ0g4SMJmdReEcUFkg9zSsD+0GGtUMVKr1L69ja9/e95Y1pnqKNGkofLoyxA
VFCP/Ulsjpz+T3H377vNW/+98EMmmWvn3LlzL6n62GwaGE5CfPcTQ4oioyFgyfFT
d2kx9ovnhWhrmhRB3AMS5f8sdcZ6Um9pFwpFbDN3hsX/zoCk
-----END CERTIFICATE-----
[root@jetnexus ~]# openssl x509 -pubkey -noout -in Azure.crt > Azure.pub; cat Azure.pub
[root@jetnexus ~]# cat Azure.pub
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp4iF0YcsKf2Hr/aaTfCB
sXzBWfDWwvgUeFYXYR/PJaiVpq63L5RWpDSsRFabsjqC2LiTp4mjlq13gQpnCig5
I9MIbtTQbKUWZr3Giv/JPBorm1ptfSKcUWDNin0tWmiYQ1HdqicbhWapzE+8o+rZ
QTJR3JOG2zDeBgJIjnV087GRQwHOB9FTotZZrG74BXuGFsRRj44DS4Bq6bglLrxM
v0ckLstoJ6LJFexrESuPEQAkXtm/lbmgDHbvZcpAAER45JgKbOm9Od572FQ3ci5s
kPWwfpeCuNBakk2fK5BN+nXOUr1M2O04Z1ekr3uVhddc1NislUrgNJJ+HDBNPbzI
cQIDAQAB
-----END PUBLIC KEY-----
3.4.4.1 DEFLATE Encoding
The signature algorithm identifier MUST be included as an additional query string parameter,
named SigAlg. The value of this parameter MUST be a URI that identifies the algorithm used to
sign the URL-encoded SAML protocol message, specified according to [XMLSig] or whatever
specification governs the algorithm.
To construct the signature, a string consisting of the concatenation of the RelayState (if present),
SigAlg, and SAMLRequest (or SAMLResponse) query string parameters (each one URL-
encoded) is constructed in one of the following ways (ordered as below):
SAMLRequest=value&RelayState=value&SigAlg=value
SAMLResponse=value&RelayState=value&SigAlg=value
The resulting string of bytes is the octet string to be fed into the signature algorithm. Any other
content in the original query string is not included and not signed.
The signature value MUST be encoded using the base64 encoding (see RFC 2045 [RFC2045]) with
any whitespace removed, and included as a query string parameter named Signature. Note that
some characters in the base64-encoded signature value may themselves require URL-encoding before being added.
echo 'SAMLRequest=jZJBa9wwEIX%2fitFdtmxL8lp4TReWgiFNIAk99BK01nhrsCVXI5P9%2bVG8LekWWnoTwzy9781Mg3qeFnXnzm4Nj%2fBjBQxJd9yTl7wfam4gp5IPOeW8rulO7Eq6q06yklr2FZQk%2bQoeR2f3pEgZSTrEFTqLQdsQS6wQlHFaiGcmFK%2bUqFJZlt9Icowuo9VhU34PYUGVZVF1BqqXBYPzkII5g4XLiunosnfKCEiSexce7IM%2fDAH8rYO8cbjMk0W1hduT1VvlNI6orJ4BVejV0%2bHLnYrMavEuuN5NpG02en%2bV%2flukEcG%2f05P2gx7T19Ea94qphZANHICbWlJT9ZxyHV8nCSWFQmpmKpkbprMmu3q2zX306I7JZ%2bdnHUf3N%2fM8zbfKaOiwtSqY9TgdjPGA%2bDP2f7PjrKdPv8%2b5ya4cbXM9i6f4aezsrIFL%2b9LHAKKO4wYuBOVFvAgtSka5qHl%2fyquyZqzZVvWH8lfx5sraNw%3d%3d&SigAlg=http%3a%2f%2fwww.w3.org%2f2001%2f04%2fxmldsig-more%23rsa-sha256' > request
echo 'MQ07yezl943nmhHi4IIw30vhXj0jjo3XckRLSRRNVjs8QIA1rU%2fZPMYm7bB9yvlzcTIEtrpT%2bOoODQNrNZn7sRJZa7Akk%2fOy2SjrENbgYCBC1VnD8iFyxmVhbrSTYZIzkR6Bb%2fc5GlEHXLOWBaORuKtXByIOtVm3LdtM2hftPqzJa6AD44r2EjbG3J%2b2bPOfP%2f7i2wL4iYLx0wqrtqEnBADV5%2bawHuhZQkXYsQ8DnzSOSgCuEReSoYRZIg8DFbB6kKMVX8cx7eGgWyE%2fyX23zPhFa5FlHnIemyCiMMGtLpaAfQE1Dzki5%2bE29YLIZ8ROlU37%2b1EtKVYfFtGv1SV7Og%3d%3d' | php -r 'echo urldecode(file_get_contents("php://stdin"));' | base64 -d > signature
[root@jetnexus ~]# openssl dgst -sha256 -verify Azure.pub -signature ./signature ./request
Verification Failure
The file request
doesn't match the string according to specification. The specification does not include a trailing "newline" \n
at the end of the string, but your echo
output does.
Use echo -n "string"
or printf %s "string"
to generate output without a trailing newline (or write the output using some other way like PHP's file_put_contents()).