I'm actually using an apex implementation of jwt for the rsa256 cryptography type using this class from github : https://github.com/salesforceidentity/jwt.

I have been able to generate a signature and the resulting token, but when I'm trying to use the below apex code to validate the signature :

 public Boolean verifySignature(String algorithmName, Blob input, Blob signature){
    string publicKey =      'MIIDCTCCAfGgAwIBAgIUWKbDV0W7B/EJ8GNEZy5uSB9zZgkwDQYJKoZIhvcNAQEL' +
                            'some lines omitted for security reason here' + 
                            '1pOkGqtTdGkIo8HGeuBp1NWwm/c2cRcn+FzM3MWYAbdvfku09L2plHvrcjd1w8bT' +

    Blob key = EncodingUtil.base64Decode(publicKey);
    return Crypto.verify(algorithmName, input, signature, key);

I am having this error :

System.SecurityException: Invalid Crypto Key

My public key and private key works well in jwt.io when trying to generate a token.

In the salesforce documentation it is written that :

The value of publicKey must be decoded using the EncodingUtilbase64Decode method, and be in X.509 standard.

This is what I have done , and my public key is a valid x.509 public key.

I generated it with openssl using the following command :

 openssl req -nodes -x509 -sha256 -newkey rsa:2048 -keyout rsa_private.pem -out rsa_public_cert.pem -days 365 -subj /CN=TEST_JWT_JAVA_XXXXX 

What can be the cause?

2 Answers 2


RS256 (RSA Signature with SHA-256) is an asymmetric algorithm that uses a public/private RSA key pair to authenticate the signature. When verifying ciphertext produced via RSA-SHA256, Crypto.verify(...) wants a RSA public key.

In case of RSA, a public key is based on a combination of two numbers (modulus and exponent). The X.509 certificate includes a public key and a bunch of other stuff, the certificate is a container that holds the public key. Most people use the terms public key and certificate interchangeably to mean the (entire) X.509 certificate. This semantic confusion causes problems when some piece of code such as Crypto.verify(...) requires a public key rather than X.509 cert. Unfortunately SF documentation is weak here and they don't explain what they're after.

You can get the public key from X.509 cert via openssl like so:

openssl x509 -in rsa_public_cert.pem -inform pem -pubkey -noout

This will produce a PEM-encoded public key:

-----END PUBLIC KEY-----

Between the BEGIN/END lines (aka "encapsulation boundaries") is base64-encoded data. PEM refers to this data as the "encapsulated text portion". Extract the encapsulated text portion and join the resulting lines into a single string. Make sure to remove all spaces after joining the lines.

If you base64-decode the resulting string and then feed it to Crypto.verify(...), it will accept your key.


format the x509 on this website and then use the command


openssl x509 -in rsa_public_cert.pem -inform pem -pubkey -noout
  • 2
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review Apr 29, 2023 at 9:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .