title: WIF ID 4036 Error - Troubleshoot, Ideas?
body: <p>I thought understood this, but I am stumped and hope someone here can add some clarity. </p>
  
  <p>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 'CN=Cin1Web07-Dev.paycor-test.com116108771XXXXXX3182074711bOkGGQaGymVHZXc9v8AsLyx/Qiy0fhmKKu88BVinXvx4ySzBMqmb1IiY7DSFAXR1PeFevfTxmzmZwu1ztPyJWpNV0LzKnVbxrqChH7iREfYhp5EHUzF0tCdJ49Q/XL3laN/Nh971hxPzj0rBQIIJ8bK/vW70x6gCkIj4Wy50Qow='. Ensure that the SecurityTokenResolver is populated with the required key)</p>
  
  <p>I've tried finding answers in the Claims Guide and Programming WIF books, but no luck.  Also, I found this site: <a href="http://consultingblogs.emc.com/simonevans/archive/2010/11/19/common-windows-identity-foundation-ws-federation-exceptions-explained.aspx" rel="nofollow">http://consultingblogs.emc.com/simonevans/archive/2010/11/19/common-windows-identity-foundation-ws-federation-exceptions-explained.aspx</a>  but it doesn't get me further either.</p>
  
  <p>If anyone has any troubleshooting tips, or ideas, I would appreciate.  Here are my details of what I'm doing:</p>
  
  <p>The STS signs the certificate with a simple cn=LocalHost, this is set here:</p>
  
  <pre><code>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));
      metadata.RoleDescriptors.Add(stsRole);
  
      // Add a contact name
      ContactPerson person = new ContactPerson(ContactType.Administrative);
      person.GivenName = "contactName";
      stsRole.Contacts.Add(person);
  
      // 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;
      stsRole.Keys.Add(signingKey);
  
      // Add endpoints
      string activeSTSUrl = WebConfigurationManager.AppSettings["ActiveSTSUrl"];
      EndpointAddress endpointAddress = new EndpointAddress(new Uri(activeSTSUrl),
                                                  null,
                                                  null, GetMetadataReader(activeSTSUrl), null);
      stsRole.SecurityTokenServiceEndpoints.Add(endpointAddress);
  
      ExposeClaimTypesOffered(stsRole);
  
      return metadata;
  }
  </code></pre>
  
  <p>and set here:</p>
  
  <pre><code>public MembershipSTSConfiguration() : base()
  {
      X509Certificate2 signingCert = CertificateUtil.GetCertificate(
          StoreName.My,
          StoreLocation.LocalMachine,
          Common.GetCertificateNameForSigningMetadata());
  
      this.SigningCredentials = new X509SigningCredentials(signingCert);
      this.SecurityTokenService = typeof(MembershipSTS);
      this.TokenIssuerName = "MembershipSTS";
  }
  </code></pre>
  
  <p>I called the method GetCertificateNameForSigningMetadata, but my understanding is that this also signs the token.</p>
  
  <p>In my RP, I have this section - and the thumbprint matches the thumbprint of the cn=localhost from the STS server:</p>
  
  <pre><code>  &lt;issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&gt;
      &lt;trustedIssuers&gt;
        &lt;add thumbprint="A6F68xxxxxxxx575EBDC" name="http://cin1web07-dev.paycor-test.com:8080/PaycorAuthServices/PassiveSTS.aspx" /&gt;
      &lt;/trustedIssuers&gt;
    &lt;/issuerNameRegistry&gt;
  </code></pre>
  
  <p>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. </p>
  
  <pre><code>  &lt;serviceCertificate&gt;
      &lt;certificateReference x509FindType="FindByThumbprint" findValue="AA310FF423XXXXXXXX910F9C69" storeLocation="LocalMachine" storeName="My" /&gt;
    &lt;/serviceCertificate&gt;
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>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,
                  System.Configuration.ConfigurationManager.AppSettings["CertificateNameForEncryptingToken"]));
  
      scope.ReplyToAddress = scope.AppliesToAddress + "/Default.aspx";
      return scope;
  }
  </code></pre>
  
  <p>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).</p>
  
  <p>Despite all this, I get the ID4036 on my dev box when I use the STS.</p>
  
  <p>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.</p>
  
  <p>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.</p>