5

I have an ASP.NET app that uses Azure ACS (and indirectly ADFS) for Authentication - which all works fine. Now I've been asked to pass the SessionToken to another backend service where it can be verified and the claims extracted. [Long Story and not my choice]

I'm having fits on the decryption side, and I'm sure I'm missing something basic.

To set the stage, the error upon decryption is:

ID1006: The format of the data is incorrect. The encryption key length is negative: '-724221793'. The cookie may have been truncated.

The ASP.NET website uses the RSA wrapper ala:

    void WSFederationAuthenticationModule_OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
        {
            string thumbprint = "BDE74A3EB573297C7EE79EB980B0727D73987B0D";

            X509Certificate2 certificate = GetCertificate(thumbprint);

            List<CookieTransform> sessionTransforms = new List<CookieTransform>(new CookieTransform[] 
            { 
                new DeflateCookieTransform(), 
                new RsaEncryptionCookieTransform(certificate), 
                new RsaSignatureCookieTransform(certificate) 
            });

            SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
            e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
        }

(the thumbprint is the same value as added by FedUtil in web.config.

I write the token with:

    if (Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.TryReadSessionTokenFromCookie(out token))
    {
        Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler th = new Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler();
        byte[] results = th.WriteToken(token);
    ...

which gives me:

    <?xml version="1.0" encoding="utf-8"?>
    <SecurityContextToken p1:Id="_53382b9e-8c4b-490e-bfd5-de2e8c0f25fe-94C8D2D9079647B013081356972DE275" 
                      xmlns:p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
                      xmlns="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512">
    <Identifier>urn:uuid:54bd1bd7-1110-462b-847e-7f49c1043b32</Identifier>
    <Instance>urn:uuid:0462b7d7-717e-4ce2-b942-b0d6a968355b</Instance>
    <Cookie xmlns="http://schemas.microsoft.com/ws/2006/05/security">AQAAANCMnd blah blah 1048 bytes total
    </Cookie>
    </SecurityContextToken>

and, with the same Certificate on the other box (and the token read in as a file just for testing), I have:

    public static void Attempt2(FileStream fileIn, X509Certificate2 certificate, out SecurityToken theToken)
        {
            List<CookieTransform> sessionTransforms = new List<CookieTransform>(new CookieTransform[] 
            { 
                new DeflateCookieTransform(),
                new RsaSignatureCookieTransform(certificate), 
                new RsaEncryptionCookieTransform(certificate) 
            });

            SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());

            // setup
            SecurityTokenResolver resolver;
            {
                var token = new X509SecurityToken(certificate);

                var tokens = new List<SecurityToken>() { token };

                resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(tokens.AsReadOnly(), false);
            }

            sessionHandler.Configuration = new SecurityTokenHandlerConfiguration();
            sessionHandler.Configuration.IssuerTokenResolver = resolver;

            using (var reader = XmlReader.Create(fileIn))
            {
                theToken = sessionHandler.ReadToken(reader);
            }

        }

and then ReadToken throws a FormatException of

ID1006: The format of the data is incorrect. The encryption key length is negative: '-724221793'. The cookie may have been truncated.

At this point, I can't tell if my overall approach is flawed or if I'm just missing the proverbial "one-line" that fixes all of this.

Oh, and I'm using VS2010 SP1 for the website (.NET 4.0) and I've tried both VS2010SP1 .NET 4.0 and VS2012 .NET 4.5 on the decoding side.

Thanks!

cleftheris
  • 4,626
  • 38
  • 55
James
  • 61
  • 3

2 Answers2

0

Does your app pool account for the backend service have read access to the certificate? If not give your app pool account for the backend service read access to the certificate. I had problems in the past with encryption/decryption because of this.

nickytonline
  • 6,855
  • 6
  • 42
  • 76
0

This might help, this will turn your FedAuth cookies into a readable XML string like:

    <?xml version="1.0" encoding="utf-8"?>
    <SecurityContextToken p1:Id="_548a372e-1111-4df8-b610-1f9f618a5687-953155F0C35B4862A5BCE4D5D0C5ADF0" xmlns:p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512">
        <Identifier>urn:uuid:c9f9b733-1111-4b01-8af3-23c8af3e19a6</Identifier>
        <Instance>urn:uuid:ee955207-1111-4498-afa3-4b184e97d0be</Instance>
        <Cookie xmlns="http://schemas.microsoft.com/ws/2006/05/security">long_string==</Cookie>
    </SecurityContextToken>

Code:

    private string FedAuthToXmlString(string fedAuthCombinedString)
    {
        // fedAuthCombinedString is from FedAuth + FedAuth1 cookies: just combine the strings
    
        byte[] authBytes = Convert.FromBase64String(fedAuthCombinedString);
        string decodedString = Encoding.UTF8.GetString(authBytes);
    
        var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        var thumbprint = "CERT_THUMBPRINT";  // from config
    
        var cert = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false)[0];
    
        var sessionTransforms = new List<System.IdentityModel.CookieTransform>(new System.IdentityModel.CookieTransform[]
        {
            new System.IdentityModel.DeflateCookieTransform(),
            new System.IdentityModel.RsaSignatureCookieTransform(cert),
            new System.IdentityModel.RsaEncryptionCookieTransform(cert)
        });
    
        SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
    
        SecurityTokenResolver resolver;
        {
            var token = new X509SecurityToken(cert);
            var tokens = new List<SecurityToken>() { token };
            resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(tokens.AsReadOnly(), false);
        }
    
        sessionHandler.Configuration = new SecurityTokenHandlerConfiguration();
        sessionHandler.Configuration.IssuerTokenResolver = resolver;
                
        var i = 0; // clear out invalid leading xml
        while ((int)decodedString[i] != 60 && i < decodedString.Length - 1) i++; // while the first character is not <

        store.Close();

        return decodedString.Substring(i);
    }
cleftheris
  • 4,626
  • 38
  • 55
naspinski
  • 34,020
  • 36
  • 111
  • 167