1
$\begingroup$

I am trying to re-calculate the digest value on an ADFS SAML token and cannot figure out how the digest has been originally calculated on the ADFS side.

The specification states that it is the SAML Assertion block that has been first transformed to a C14N format and then hashed using a SHA256 hashing algorithm.

I have done this and it does not seem to be correct.

I have also tried multiple other hashing algorithms, and a non-C14N format and still have had no luck.

Any help would be much appreciated.

Edit:

I think the signature value may need to be removed, but I have tried both removing the node and the inner text. Still no luck.

The ADFS token looks like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <s:Header>
       <a:Action s:mustUnderstand="1">http: //docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal</a:Action>
       <a:RelatesTo>urn:uuid:2041e0fc-7729-4cdf-b45e-2781936781f4</a:RelatesTo>
       <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <u:Timestamp u:Id="_0">
               <u:Created>2021-04-12T13:40:45.195Z</u:Created>
               <u:Expires>2021-04-12T13:45:45.195Z</u:Expires>
           </u:Timestamp>
       </o:Security>
   </s:Header>
   <s:Body>
       <trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
           <trust:RequestSecurityTokenResponse>
               <trust:Lifetime>
                   <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2021-04-12T13:40:45.180Z</wsu:Created>
                   <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2021-04-12T14:40:45.180Z</wsu:Expires>
               </trust:Lifetime>
               <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
                   <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                       <wsa:Address>urn:sharepoint:sfbr-sp</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <trust:RequestedSecurityToken>
                   <saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_ea3b87dd-f35b-4a62-88c8-7bc7e912a183" Issuer="http://sfbr-adfs.sfbr.local/adfs/services/trust" IssueInstant="2021-04-12T13:40:45.195Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
                       <saml:Conditions NotBefore="2021-04-12T13:40:45.180Z" NotOnOrAfter="2021-04-12T14:40:45.180Z">
                           <saml:AudienceRestrictionCondition>
                               <saml:Audience>urn:sharepoint:sfbr-sp</saml:Audience>
                           </saml:AudienceRestrictionCondition>
                       </saml:Conditions>
                       <saml:AttributeStatement>
                           <saml:Subject>
                               <saml:SubjectConfirmation>
                                   <saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
                               </saml:SubjectConfirmation>
                           </saml:Subject>
                           <saml:Attribute AttributeName="upn" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                               <saml:AttributeValue>seb@sfbr.local</saml:AttributeValue>
                           </saml:Attribute>
                           <saml:Attribute AttributeName="givenname" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                               <saml:AttributeValue>Seb</saml:AttributeValue>
                           </saml:Attribute>
                           <saml:Attribute AttributeName="surname" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                               <saml:AttributeValue>Adamo</saml:AttributeValue>
                           </saml:Attribute>
                       </saml:AttributeStatement>
                       <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:X509-PKI" AuthenticationInstant="2021-04-12T13:40:45.164Z">
                           <saml:Subject>
                               <saml:SubjectConfirmation>
                                   <saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
                               </saml:SubjectConfirmation>
                           </saml:Subject>
                       </saml:AuthenticationStatement>
                       <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="#_ea3b87dd-f35b-4a62-88c8-7bc7e912a183">
                                   <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>RbUsDFIkc4IgbIvcCVOLm05PHm+CxvE2IUokkjzXg8c=</ds:DigestValue>
                               </ds:Reference>
                           </ds:SignedInfo>
                           <ds:SignatureValue>Sy4u3C1yW+miawQw0npYa65hlJyXNpAwzzilWlRCxwwIGpD4UWEUEZJC/+ezrS98vY6+34sRksr7AMV2+TAZ7xB7xJXJ1Ow/w7vrSd8dDxKiwXTCfjTxkEQ3aJbahYuOuYKQZItPGi/N/Ud1UlYoTahdIhBNo2EnOMk9uSOPb3o4nXfIQ3ZmfN4pKakHfO8jw+r2ScrDioVczsUpb4M6xwsFGSwGGwaLYoNtdMZOxQlQqm11yi/A9uUpX0M0HtN4EF+vAm2/iFVlS0yZ/c4S0hkv5u4iP0vwuqEYIV5V95/BkxixUEu7xHzybYQPuBcyX55Kz+xdz8BwCClQGQxwJA==</ds:SignatureValue>
                           <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                               <X509Data>
                                   <X509Certificate>MIIFOjCCBCKgAwIBAgITIgAAGk1/IAickxaJQwAAAAAaTTANBgkqhkiG9w0BAQsFADBHMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFDASBgoJkiaJk/IsZAEZFgRzZmJyMRgwFgYDVQQDEw9zZmJyLVNGQlItREMtQ0EwHhcNMjEwMjA2MTIxMjEzWhcNMjIwMjA2MTIxMjEzWjAfMR0wGwYDVQQDExRTRkJSLUFERlMuc2Zici5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIyo5T9XJeJfJWTJ9FBnW7F04v9fS2Gz2PD8Kvu1HkvqdeZ7yajAPBI/lSrVNc++D2G3W5HJ1C+aevTF+ytCqSu0DaKbbQ01eeDlCV/aDjQlJ1ZbP6RwPv4ZEY65y39VMRSiw1d13yUmMzPntrencAJXX2obB7PXPe7Qs3pzyqcXFahzK+hz/hPQryDFeSz0q6l0g3zPXOAz8ga5cm/beT5ouSA0KWHGT903A+b+rtWpPxbMXg75CFeIKLdWCAYKWn8iGHXvoJ+emujcpscRlQkecMkIB7cgDKuyeg4TmiAeE/xhXL9QhgdCWCKElVKkpqenvYMBVzhLKem2hHD9Qi8CAwEAAaOCAkUwggJBMB0GCSsGAQQBgjcUAgQQHg4ATQBhAGMAaABpAG4AZTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMB8GA1UdEQQYMBaCFFNGQlItQURGUy5zZmJyLmxvY2FsMB0GA1UdDgQWBBR2PQ55WhiQQAHZu6oe9JZl0/qb2jAfBgNVHSMEGDAWgBQehDpGasT+z7tB11CTogkLtp+LGDCBzAYDVR0fBIHEMIHBMIG+oIG7oIG4hoG1bGRhcDovLy9DTj1zZmJyLVNGQlItREMtQ0EsQ049U0ZCUi1EQyxDTj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1zZmJyLERDPWxvY2FsP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDCBwAYIKwYBBQUHAQEEgbMwgbAwga0GCCsGAQUFBzAChoGgbGRhcDovLy9DTj1zZmJyLVNGQlItREMtQ0EsQ049QUlBLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9c2ZicixEQz1sb2NhbD9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAQEAuFon2UGq/g1n7xh6eo7hq2bUIXOOGpLzFuS7GE3Xg2/CfAx1WtoXwxsdc21M5VzkBQvnsrpV7hX61PHfajKnLP0LnVwgAfL6vhk5zRWmLQZljX651mFwePIVwQyOtvdTmb9k7dU6kFg3m43gTYqJVAbcWuD1Ixd33ygtBAwLj87VaL22PtLn/20zuhjVXmt5YAqeBZ87M/bGO+wpu5bdlbhVU43mAuNbEAWftKX0jco010JnxzB7JzfvAT00jsYpVvNsxvED35YFAPM+9nbUSIMxD4P2orUm2BJ3283GnrdslyFo8/DbWlWPtOljBtNf0XklzKMmceluhdihWx0X0Q==</X509Certificate>
                               </X509Data>
                           </KeyInfo>
                       </ds:Signature>
                   </saml:Assertion>
               </trust:RequestedSecurityToken>
               <trust:RequestedAttachedReference>
                   <o:SecurityTokenReference k:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:k="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                       <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">_ea3b87dd-f35b-4a62-88c8-7bc7e912a183</o:KeyIdentifier>
                   </o:SecurityTokenReference>
               </trust:RequestedAttachedReference>
               <trust:RequestedUnattachedReference>
                   <o:SecurityTokenReference k:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:k="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                       <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">_ea3b87dd-f35b-4a62-88c8-7bc7e912a183</o:KeyIdentifier>
                   </o:SecurityTokenReference>
               </trust:RequestedUnattachedReference>
               <trust:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</trust:TokenType>
               <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
               <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
           </trust:RequestSecurityTokenResponse>
       </trust:RequestSecurityTokenResponseCollection>
   </s:Body>
</s:Envelope>

And the C# like this:

class Program
{
    static void Main(string[] args)
    {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load("new token.xml");

        XmlNode sigVal = xmlDocument.GetElementsByTagName("ds:SignatureValue")[0];

        // Removing Node
        //xmlDocument.GetElementsByTagName("ds:Signature")[0].RemoveChild(sigVal);

        // Removing Inner Text
        sigVal.InnerText = string.Empty;


        string digestValue = xmlDocument.GetElementsByTagName("ds:DigestValue")[0].InnerText;
        string samlAssertionBlock = C14N(xmlDocument.GetElementsByTagName("saml:Assertion")[0].OuterXml);

        using (SHA256 sha256Hash = SHA256.Create())
        {
            string samlAssertionBlockHash = Convert.ToBase64String(sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(samlAssertionBlock)));
            Console.WriteLine("Block: " + samlAssertionBlockHash);

            // Digest Value
            Console.WriteLine("Digest: " + digestValue);
        }
    }

    public static string C14N(string xml)
    {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(xml);

        XmlDsigC14NTransform xmlDsigC14 = new XmlDsigC14NTransform
        {
            Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#",
        };

        xmlDsigC14.LoadInput(xmlDocument);

        using (StreamReader streamReader = new StreamReader(xmlDsigC14.GetOutput() as Stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
$\endgroup$
6
  • $\begingroup$ make sure you hash it with the correct encoding... ascii utf-8 , 16, each give a different hash $\endgroup$ Apr 9 at 14:20
  • $\begingroup$ Have tried all 3 and still had no luck $\endgroup$ Apr 9 at 14:43
  • 1
    $\begingroup$ Make sure no extra space or newline is included... like echo -n "mystring" | openssl dgst .... Due to the cascading effect the smallest change will provide a totally different hash. Use onesaml or a browser extension to track saml parameters... inflate, base64decode then analize. $\endgroup$ Apr 9 at 15:10
  • $\begingroup$ Since you mentioned ADFS I am thunking there is a newline written microsoft style as /r/n and not \n $\endgroup$ Apr 9 at 15:33
  • $\begingroup$ You may want to post the concrete values. $\endgroup$
    – SEJPM
    Apr 9 at 17:58
1
$\begingroup$

So the answer was to remove the entire <ds:Signature> node from the saml:Assertion node before hashing the block, as opposed to removing the <ds:SignatureValue> node.

$\endgroup$
1
  • $\begingroup$ Obviously, a signed document must have a mechanism to get itself out of the catch-22 situation doesn't it? $\endgroup$
    – DannyNiu
    Apr 13 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.