AADSTS700027: The certificate with identifier used to sign the client assertion is not registered on application

Kevin F 0 Reputation points
2025-04-30T20:24:32.99+00:00

I have tried every combination of hashing for my certificate fingerprint to get this to work and I can see it in the decoded JWT as matching, however I continually get this error. I am on Mac using Node v22 and Javascript with the jsonwebtoken npm package to sign the JWT along with the X509Certificate object from crypto library.

AADSTS700027: The certificate with identifier used to sign the client assertion is not registered on application. [Reason - The key was not found., Thumbprint of key used by client: '37453...']

I verified the thumbprint in App screen matches what's in the JWT. All based on this https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials . I also verified the JWT on JWT.io with my client cert successfully.

{
  "error": "invalid_client",
  "error_codes":[700027],
  "timestamp":"2025-04-30 19:04:43Z",
  "trace_id":"be394a13-f183-4421-8686-05919fdd0000",
  "correlation_id":"07124932-dce6-433d-b10a-3b43753b8184",
  "error_uri":"https://login.microsoftonline.com/error?code=700027"
}
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
24,563 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Kevin F 0 Reputation points
    2025-05-01T20:27:20.7733333+00:00

    Oh geez.. After what seems like a century, I finally found a reference from a reference in some random StackOverflow article pointing to a different problem in a different place.

    For anyone else heading this way (and using 'pure' JS):

    import { v4 as uuidv4 } from 'uuid';
    import jwt from 'jsonwebtoken';
    import { X509Certificate } from 'crypto';
    
    // load public cert and then the key
    //   (you can create private key if you use encrypted pk here as well
    const newCert = new X509Certificate(readFileSync('./NewCert.pem'));
    const keyPEM = readFileSync('./NewCert.key');
    
    // helper function to convert fingerprint to proper encoding
    function hexToBase64(hexString) {
      // Ensure even number of hex digits
      if (hexString.length % 2 !== 0) {
        hexString = "0" + hexString;
      }
    
      // Convert hex to bytes
      const bytes = new Uint8Array(hexString.length / 2);
      for (let i = 0; i < hexString.length; i += 2) {
        bytes[i / 2] = parseInt(hexString.slice(i, i + 2), 16);
      }
    
      // Convert bytes to base64
      const base64String = btoa(String.fromCharCode(...bytes));
      return base64String;
    }
    
    const getJWT = () => {
      // You have to get the hex value of the fingerprint
      // convert each pair to base-16
      // mash back together and base64 it
      const fingerprint = hexToBase64(newCert.fingerprint.replace(/:/g, ''));
    
      // create and sign JWT
      const JWT = jwt.sign(
        {},
        { key: keyPEM }, // can include the passphrase here if using encrypted pk
        {
          issuer: "<CLIENT_ID>",
          subject: "<CLIENT_ID>",
          expiresIn: 60 * 60, // time in seconds - 1h in this case
          notBefore: 0,
          jwtid: uuidv4(),
          audience: "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token",
          algorithm: 'RS256',
          header: {
            x5t: fingerprint,
          }
      });
    
      return JWT;
    }
    
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.