STS and Relying Party Encryption Setup

Jul 25, 2011 at 2:16 PM

I am stumped and hope someone here can add some clarity. 

I have written a custom STS.  I have written a separate, simple Relying Party that outputs the claims of the STS.  It works on my local machine.  I can make it work if I deploy the STS and RP to the same server.  However, trying to run an RP from my dev box, hitting the dev server, I get ID4036 errors (ID4036: The key needed to decrypt the encrypted security token could not be resolved from the following security key identifier '<KeyInfo xmlns=""><e:EncryptedKey xmlns:e=""><e:EncryptionMethod Algorithm=""><DigestMethod Algorithm="" /></e:EncryptionMethod><KeyInfo><o:SecurityTokenReference xmlns:o=""><X509Data><X509IssuerSerial><X509IssuerName></X509IssuerName><X509SerialNumber>116108771XXXXXX3182074711</X509SerialNumber></X509IssuerSerial></X509Data></o:SecurityTokenReference></KeyInfo><e:CipherData><e:CipherValue>bOkGGQaGymVHZXc9v8AsLyx/Qiy0fhmKKu88BVinXvx4ySzBMqmb1IiY7DSFAXR1PeFevfTxmzmZwu1ztPyJWpNV0LzKnVbxrqChH7iREfYhp5EHUzF0tCdJ49Q/XL3laN/Nh971hxPzj0rBQIIJ8bK/vW70x6gCkIj4Wy50Qow=</e:CipherValue></e:CipherData></e:EncryptedKey></KeyInfo>'. Ensure that the SecurityTokenResolver is populated with the required key)

I've tried finding answers in the Claims Guide and Programming WIF books, but no luck.  Also, I found this site:  but it doesn't get me further either.

If anyone has any troubleshooting tips, or ideas, I would appreciate.  Here are my details of what I'm doing:

The STS signs the certificate with a simple cn=LocalHost, this is set here:

    public static MetadataBase GetFederationMetadata()
        string endpointId = WebConfigurationManager.AppSettings["ActiveSTSUrl"];
        EntityDescriptor metadata = new EntityDescriptor();
        metadata.EntityId = new EntityId(endpointId);

        // Define the signing key
        X509Certificate2 cert = CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, GetCertificateNameForSigningMetadata());
        metadata.SigningCredentials = new X509SigningCredentials(cert);

        // Create role descriptor for security token service
        SecurityTokenServiceDescriptor stsRole = new SecurityTokenServiceDescriptor();
        stsRole.ProtocolsSupported.Add(new Uri(WSFederationMetadataConstants.Namespace));

        // Add a contact name
        ContactPerson person = new ContactPerson(ContactType.Administrative);
        person.GivenName = "contactName";

        // Include key identifier for signing key in metadata
        SecurityKeyIdentifierClause clause = new X509RawDataKeyIdentifierClause(cert);
        SecurityKeyIdentifier ski = new SecurityKeyIdentifier(clause);
        KeyDescriptor signingKey = new KeyDescriptor(ski);
        signingKey.Use = KeyType.Signing;

        // Add endpoints
        string activeSTSUrl = WebConfigurationManager.AppSettings["ActiveSTSUrl"];
        EndpointAddress endpointAddress = new EndpointAddress(new Uri(activeSTSUrl),
                                                    null, GetMetadataReader(activeSTSUrl), null);


        return metadata;

and set here:

    public MembershipSTSConfiguration() : base()
        X509Certificate2 signingCert = CertificateUtil.GetCertificate(

        this.SigningCredentials = new X509SigningCredentials(signingCert);
        this.SecurityTokenService = typeof(MembershipSTS);
        this.TokenIssuerName = "MembershipSTS";

I called the method GetCertificateNameForSigningMetadata, but my understanding is that this also signs the token.

In my RP, I have this section - and the thumbprint matches the thumbprint of the cn=localhost from the STS server:


      <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
          <add thumbprint="A6F68xxxxxxxx575EBDC" name="" />


I believe that is all configured correctly.  However, the encryption part is where I think there is a problem.  This is in the RP's web.config.  The Thumbprint below references a certificate called RelyingParty.MyOrg. 


        <certificateReference x509FindType="FindByThumbprint" findValue="AA310FF423XXXXXXXX910F9C69" storeLocation="LocalMachine" storeName="My" />

The certificate is installed on my development machine (the RP) along with the private key.  The Certificate Authority also exists on my machine.  I exported the certificate to the dev server and the CA cert.  They seem to be setup correctly.  In the GetScope of the STS, I have this:

    protected override Scope GetScope(IClaimsPrincipal principal, RequestSecurityToken request)
        Scope scope = new Scope(request.AppliesTo.Uri.AbsoluteUri, SecurityTokenServiceConfiguration.SigningCredentials);
        scope.EncryptingCredentials = new X509EncryptingCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine,

        scope.ReplyToAddress = scope.AppliesToAddress + "/Default.aspx";
        return scope;

The AppSetting maps to cn=RelyingParty.MyOrg, and is finding the certificate I believe (because if I change 1 letter, I get a different 'can't find cert' error).

Despite all this, I get the ID4036 on my dev box when I use the STS.

Here is the part that REALLY stumps me - after changing to the RelyingParty.MyOrg cert, the RP on the dev server still works - even though it is set to the old cn=localhost and does not have the private key for the cn=RelyingParty.MyOrg.

So clearly, I do not understand some of this config.  I apologize for the lengthy post, but I am really getting desperate to wrap this up.  If anyone has any suggestions, I would greatly appreciate it.

ID4036: The key needed to decrypt the encrypted security token could not be resolved from the following security key identifier '<KeyInfo xmlns=""><e:EncryptedKey xmlns:e=""><e:EncryptionMethod Algorithm=""><DigestMethod Algorithm="" /></e:EncryptionMethod><KeyInfo><o:SecurityTokenReference xmlns:o=""><X509Data><X509IssuerSerial><X509IssuerName></X509IssuerName><X509SerialNumber>116108771798210860686154714333182074711</X509SerialNumber></X509IssuerSerial></X509Data></o:SecurityTokenReference></KeyInfo><e:CipherData><e:CipherValue>bOkGGQaGymVHZXc9v8AsLyx/Qiy0fhmKKu88BVinXvx4ySzBMqmb1IiY7DSFAXR1PeFevfTxmzmZwu1ztPyJWpNV0LzKnVbxrqChH7iREfYhp5EHUzF0tCdJ49Q/XL3laN/Nh971hxPzj0rBQIIJ8bK/vW70x6gCkIj4Wy50Qow=</e:CipherValue></e:CipherData></e:EncryptedKey></KeyInfo>'. Ensure that the SecurityTokenResolver is populated with the required key.

Jul 25, 2011 at 8:40 PM

Nevermind... after a great deal of time, this was actually related to configuration of other legacy apps.  It's a long story and I am surprised this ever worked even locally.