'SAML Authentication Requested ( Invalid Signature Error)
I am creating signed SAML Request using below code and the certificates are cross checked to be same however getting invalid signature error on IDP , Please suggest
public XmlDocument SignXML(XmlDocument xml)
{
X509Certificate2 cert = new X509Certificate2(@"" + SPCertificateLocation, SPCertificatePassword);// , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// set key, signing algorithm, and canonicalization method
var signedXml = new SignedXml(xml.DocumentElement) { SigningKey = cert.GetRSAPrivateKey() };
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
//signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// sign whole document using "SAML style" transforms
var reference = new Reference { Uri = string.Empty };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data(cert);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;
// create signature
signedXml.ComputeSignature();
// get signature XML element and add it as a child of the root element
//signedXml.GetXml();
//XmlElement xmlSignature = signedXml.GetXml();
//AssignNameSpacePrefixToElementTree(xmlSignature, "ds");
// Add prefix "ds:" to signature
XmlElement signature = signedXml.GetXml();
SetPrefix("ds", signature);
// Load modified signature back
signedXml.LoadXml(signature);
// this is workaround for overcoming a bug in the library
signedXml.SignedInfo.References.Clear();
// Recompute the signature
signedXml.ComputeSignature();
string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
// Replace value of the signature with recomputed one
ReplaceSignature(signature, recomputedSignature);
// Append the signature to the XML document.
xml.DocumentElement.InsertAfter(xml.ImportNode(signature, true), xml.DocumentElement.FirstChild);
//xml.DocumentElement?.AppendChild(signedXml.GetXml());
return xml;
}
The code converts the XML correctly into signature enabled XML however it is showing unable to verify the authenticity of signature
<saml2p:AuthnRequest ID="_3a6d2566-68a1-4afc-a784-c125bd94173f" Version="2.0" ForceAuthn="false" IssueInstant="2022-05-09T08:26:33Z" Destination="https://auth.pingone.com/172e7894-5cbe-456b-b451-d2585aeab74f/saml20/idp/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://localhost:20630/CASCC/SamlConsume" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:20630</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><ds:Reference URI=""><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><ds:DigestValue>EZBisrHSVKE2zS15roaUFG0EnP3ZobisulcQXw0fO18=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>uyniiynlIP6z/g6U4qzWKdmeD8sP7majYwqDhy5n2nTDJyE8MEdaIhEJssIDeuc+VAILueMhzRV/mC4uiAZ5kgAYDa0LYnaO3673dCvuFJPgQxKbJUWYSTnfY89x/VYXsFm6kKgR2pxyGgq4VYGK9W/vvpIi+PKkYwCKtjjb8LKin/zoCPAA7UecMS9mxPeJ/ntdEfjIGTwBcoETsFRRNdVToTdVtQJjc4LBa/5FnJbGNRKFIdRDqx+wr7IbaT+08o5yl+UI2Qogly8JxeOPolVUr94rLXKyY1/n2nkXr+5LoY/sRomoCNJ11wLsMUEmg11j4J3bB93FGtlnmpwm4Q==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIEFzCCAv+gAwIBAgIUeUS7jZnkZLcxjRUQ5uhqrAI7z2gwDQYJKoZIhvcNAQELBQAwgZoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGQm9zdG9uMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xFDASBgNVBAMMC0NvbW1hbmRDb21tMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMB4XDTIyMDQxNTExNDk1MloXDTIzMDQxNTExNDk1MlowgZoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGQm9zdG9uMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xFDASBgNVBAMMC0NvbW1hbmRDb21tMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyTHXlPSUCzHLGXkoSkuXTh2/oONTe+5TcswtFTnq6VDZnZ3m1tNs2EWcOXq6lVjSlfaqByCHUSGa0O54qMAD2WdZjTv08GQS1uYtJhjQvi58P32ost2LBEKYhtyaw8fen81OwJq+tiDHCw8xrx/z610rHGQVRrSojmqC6zLOclkQmrfpAhC2L+enovxfl6xW0FzYJETFYv/jW0ACcaZJBtFb7AfYDlCzvajUQ+dGTpZE1/0UOGdOTNjbMezGxFDyndcJ4ZLQItbG0cE3c1fEQkU06OYgPoOeXGsHM2w1R498oS/pk1ZLB1LtDUfKl7PVmjJGoytCi38Huft/95u0JQIDAQABo1MwUTAdBgNVHQ4EFgQUawg+tyAVohufNTVu7RXqPtu+B4MwHwYDVR0jBBgwFoAUawg+tyAVohufNTVu7RXqPtu+B4MwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAPom0ZUQx3OWXlO7R5Goyv7cEepq+Nikd82chqzUvwhXW5Azb3xsC+cgh0srjYlrRC9QJk7m43yQE1xa0DM4aKi/rA/l9rLJpXfjQj+97V0SA8JMrCxbcxdN+v2mN1vp8xprJ2i+nPtCBPqLM2XA0kUQ44zeygCm+L78zElYu79r3YF6ObzA9D3/Fa794zFWqI/1ggmOdI4T3kzUgFxv1YMTYZ8rgWcICVs1mSU2zkT5ScJq0NJPENR0jpzFHzirzIJUgnAcOWnCnzyCKDgpJI/+9yJNzLaR97LHk12cVfQMuBvLcchRian08sZ/J4a440h54bB9EByp+853rUpHhVQ==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></saml2p:AuthnRequest>
As @timothy suggested i added the Id = "#" + Id
and below is the XML generated
<saml2p:AuthnRequest ID="_35ab8f46-0ba1-4a29-a153-b02e97bf1397" Version="2.0" ForceAuthn="false" IssueInstant="2022-05-10T09:25:33Z" Destination="https://auth.pingone.com/172e7894-5cbe-456b-b451-d2585aeab74f/saml20/idp/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://localhost:20630/CASCC/SamlConsume" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:20630</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><ds:Reference URI="#_35ab8f46-0ba1-4a29-a153-b02e97bf1397"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><ds:DigestValue>0iGmT3qeJrHVXJveUe5AboRo65hxD25OjVpbbxWvbUo=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>InYJ2yGLSnL9Q2BVaWBfABpcpiViFgZH6XnvhYU0I67sPI/KTb6g39MZMBM4XiUDNTpjGXHcZn9c2elh+NnVAx/SPX8R0Yjq7dKiVe+Zz6BFKk0DCSA9Q2APFCk2uJZVlvKza3tIjoxrBvQuxZcNZxsMOUm8LEWnhQ3ElgN7pisHj5AiAzc/VluPIl21BG+tTolV/Ab7bg+B7YdBwK4++QEyK0R7dsYoZex+NsLf1+zel1xWg2PbZgTXOi4PXFB9RvIPXDUtfMPCSOUQRUdgbI6GeV5X+ZWCGOs0m0FnnZD7hL1WR1sWOcHUgY0DSIpgtToJintjx0f5HphidWZF9/sjP+zR9QEOtkcBMYl9JacO5tbNp49fZSVuuqN2pMxcSCE2BmPdoWw1t/CHrKFOzOfNyNQsvauP2UpufQQt+lxUePpvE7VZNuXYQ+hGv74FkBpy6NU58x3agqOP0NeMsyrT+R0AOSTCXWqzfogYIOR9t/mOFMTohKJqjPXB7H2+LrlOcmQM/+HHUf21F4KP6w2ujbFESOgCZmoyou0gBDEAtT4xbYvwnplZwSbYaKHQQhunyzesfqtdF8bY9+0jVsfj0+e7tzofoURb+d6HMtbJxDnIg4VUzmI2QHEUhNJzT1nAS2cbVieP/kGzmLQ9TKGhYdTUnWVa16oXZz+qkeo=</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIFqDCCA5ACFAQ5F+2NYAb4N/enCOaeA/V2IVPYMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYDVQQGEwJVUzELMAkGA1UECAwCVVMxCzAJBgNVBAcMAk5ZMRQwEgYDVQQKDAtDb21tYW5kQ29tbTEUMBIGA1UECwwLQ29tbWFuZENvbW0xCzAJBgNVBAMMAkNDMSswKQYJKoZIhvcNAQkBFhxha2Fwb29yQGNvbW1hbmRjb21wYW5pZXMuY29tMB4XDTIyMDUwOTEyMDcyNVoXDTIzMDUwOTEyMDcyNVowgZIxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJVUzELMAkGA1UEBwwCTlkxFDASBgNVBAoMC0NvbW1hbmRDb21tMRQwEgYDVQQLDAtDb21tYW5kQ29tbTEQMA4GA1UEAwwHQ29tbWFuZDErMCkGCSqGSIb3DQEJARYcYWthcG9vckBjb21tYW5kY29tcGFuaWVzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKoMSbgGecTY5d6bNjCEnpX2YxY+QRNDT0v/zGpO23PZlt+fuaYHr+b0hP3R/3cCxVTmd36o6MNASjT/slq8aFTdk49sW/zwICNa5AtjRRBVHGOmNYz/ntbo1KIQzC1faoGg+1CiTBL/vflQN4EWMyKGg/GfyIeKLODmOzzx41U5Y/Bv22X8bMmnFgYtwBMh2c7X0hNysqUmkc81sJ5cDgcwNbU4tu+sLslxI+1iOmmDtZBfcYmn+5vU4lFy8XZIODqN0eWpOyvH+a6r6rhAe9vIPwjWv2oh1Ktw0HE3b4JIgk/Vk4YvHKeSTjeC0biue7EF1c0sexOac5KpRhaWNxY4tmHY0dxKT1I21ls7TFd1x9E9A+n5Ff+INb9O4V0OmTrJUiXHZ44vpOi2kv1zbf2lSVFXwF6fhcb1KqxP2XQUMr7Fs6P5JUuH9h1AB5Kf7pjcrza7jjWU3LFRQzwISnJZNV+g1f62VM1S3AHpn1YFaI49Kpn9k5kuqWgGPUlIJq+9tWIy19lL6D3vzYI4yzZR4sGp8NcdSlKR8FgMgfB3bU4DtP85agoEOQ5C2DKV8No3jLVEJ8qFMhn/kLzcDy9oWF7ZVQGUmYuNo0q5T9O4dXcX0alXx0PS9UKJwfw23sGfUenwLI9HZEAqK5f3UEaDnfFmhxlajIAMj2hPldODAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAL4Fr2RzIH0O4VJRgYQr1ASeSghzijkhSHpjmL3fCEVrS7WvYtgKr3gXC5tQ/8i3Immh2aqMmbmq1gk/885frCMW76e0I1ZRfSw0ktUa04WlftVLeg9lzqPEmNKwaxzSudcR+WdEnLKrm3DHXltXqXw2yuDzy1SWGeyfZ+Lq62geahBkGWn5YoQqsxbmvhFDZNtDvinUI0GsbmTEsv9oxdWGGfl0spg6y0cO5WW/8fTh6Jrpk2RjOWcx7wUChQbv/Wu4WH9S7g78/F5HSy5hQ2PTg/CVtFXt/zScj6pxXb0Uov4/PXE7zHyLPUqtOxgasov4FurDJZaxUVNE5hu9OVLiHmw0jyU0t6myON+B4+a6I2xeWDBe1EQJyK2G22yISN6o4UILD3YL3gnl/xZoe/64sKP59RU0Gxv3pyYTpCtp+DYR8xYWzN8hVG0KHlxSypkh0TwQ7a4H4x5LOXZ5Qinr1qHgjgJY9LCAYHfvX6i+pctsd+na8ZUEPKZH/ARFz1LDx0RS5RbZhsnyn7GkpJZEuUUeS+aOYkuFLlvBopcKnP8KmKXjjRmrhHaNhPhnK8cJgai377uNk87xUt2WnMankROZajIK+7M6xMTq5WgmmDPE16o6zp+mdn5I8RzglelDFtgCAf9Hz2vupH4v8fcg772fzIf277zZpl8RZc36</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></saml2p:AuthnRequest>
However when i try to validate it using https://tools.chilkat.io/xmlDsigVerify.cshtml
I get valid signature but https://console.pingone.com/ says invalid signature so may be certificates is the one i suggest it is blocking something please suggest
My Latest code looks like
public XmlDocument SignXML(XmlDocument xml)
{
X509Certificate2 cert = new X509Certificate2(@"" + SPCertificateLocation, SPCertificatePassword);// , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// set key, signing algorithm, and canonicalization method
var signedXml = new SignedXml(xml.DocumentElement) { SigningKey = cert.GetRSAPrivateKey() };
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
//signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// sign whole document using "SAML style" transforms
var reference = new Reference { Uri = "#"+_id };
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data(cert);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;
// create signature
signedXml.ComputeSignature();
// get signature XML element and add it as a child of the root element
//signedXml.GetXml();
//XmlElement xmlSignature = signedXml.GetXml();
//AssignNameSpacePrefixToElementTree(xmlSignature, "ds");
// Add prefix "ds:" to signature
XmlElement signature = signedXml.GetXml();
SetPrefix("ds", signature);
// Load modified signature back
signedXml.LoadXml(signature);
// this is workaround for overcoming a bug in the library
signedXml.SignedInfo.References.Clear();
//var reference2 = new Reference { Uri = "#" + _id };
//reference2.AddTransform(new XmlDsigEnvelopedSignatureTransform());
//reference2.AddTransform(new XmlDsigExcC14NTransform());
//signedXml.AddReference(reference2);
// Recompute the signature
signedXml.ComputeSignature();
string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
// Replace value of the signature with recomputed one
ReplaceSignature(signature, recomputedSignature);
// Append the signature to the XML document.
xml.DocumentElement.InsertAfter(xml.ImportNode(signature, true), xml.DocumentElement.FirstChild);
//xml.DocumentElement?.AppendChild(signedXml.GetXml());
return xml;
}
Solution 1:[1]
I was able to validate your XML with perl's XML::Sig after a few changes that I had to make to XML::Sig since it does not currently support SignedInfo without an ID.
https://tools.chilkat.io/xmlDsigVerify.cshtml also validates it fine so the issue is likely in your validation code that you did not show.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Timothy Legge |
