question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

verify RS256 signature failing

See original GitHub issue

Since updating PyJWT to v4.1 (from v3.2) we are no longer able to verify RS256 signed messages.

I now get a “Could not unserialize key data” ValueError exception. This stack trace shows the relevant place that the error occurs:

Traceback (most recent call last):
  File "/Users/username/Projects/platform-api/flaskapp/api_v1/views.py", line 247, in verify_LCD_token_internal
    jwt.verify_signature(token, signing, header, signature, subjectPublicKeyInfo)
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/jwt/__init__.py", line 365, in verify_signature
    key = prepare_key_methods[algorithm](key)
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/jwt/__init__.py", line 156, in prepare_RS_key
    key = load_pem_public_key(key, backend=default_backend())
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/cryptography/hazmat/primitives/serialization.py", line 48, in load_pem_public_key
    return backend.load_pem_public_key(data)
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/cryptography/hazmat/backends/multibackend.py", line 325, in load_pem_public_key
    return b.load_pem_public_key(data)
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 699, in load_pem_public_key
    None,
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 761, in _load_key
    self._handle_key_loading_error()
  File "/Users/username/.virtualenvs/api-test/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 833, in _handle_key_loading_error
    raise ValueError("Could not unserialize key data.") 

I’m not sure exactly which version this stopped working, but I assume it was when the crypto library dependancy switched from PyCrypto to cryptography

If there’s anything else relevant that I can provide, then please ask. Cheers Buzzrick

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:23 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
mark-adamscommented, Jan 25, 2015

Thanks @buzzrick. Generally speaking, it is safe to share the RSA public key publicly (hence the name) as long as you don’t share the RSA private key. I’ve had a chance to look over what you sent me and I think I’ve figured out where the issue lies.

PyJWT’s documentation talks about accepting two kinds of RSA public keys: PEM and SSH format. PEM keys start with “-----BEGIN PUBLIC KEY-----” and SSH format keys start with “ssh-rsa”. The file you sent me starts with “-----BEGIN CERTIFICATE-----” indicating that it is a x509 certificate in PEM format. A certificate is actually a public key accompanied by certain statements about that key (who owns it, how long it is valid, etc.) that are together digitally signed by a third-party authority who is vouching for its authenticity. However, an x509 certificate is not exactly an RSA key in PEM format… even though it does actually contain the RSA public key. That is why you are getting an error.

I was curious so I went back to v0.3.2 (cd32cf25) and ran the following:

>>> cert = open('certificate.cer', 'r').read()
>>> import jwt
>>> jwt.prepare_RS_key(cert)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "jwt/__init__.py", line 105, in prepare_RS_key
    key = RSA.importKey(key)
  File "/home/mark/.venv/pyjwt/local/lib/python2.7/site-packages/Crypto/PublicKey/RSA.py", line 665, in importKey
    return self._importKeyDER(der)
  File "/home/mark/.venv/pyjwt/local/lib/python2.7/site-packages/Crypto/PublicKey/RSA.py", line 588, in _importKeyDER
    raise ValueError("RSA key format is not supported")
ValueError: RSA key format is not supported

It seems like the v0.3.2 also rejects x509 certificates so I’m not sure how it was working before unless something changed with regards to how you were generating your keys. At any point in time did you change from generating PEM public keys to generating PEM x509 certificates?

The good news is… there are some easy workarounds to solve this problem since the RSA public key can be extracted from the x509 certificate.

First, OpenSSL can extract the key for you in PEM format by running the following command:

openssl x509 -in certificate.cer -noout -pubkey > public_key.pem

You can then read public_key.pem in and use it as the key in PyJWT.

Second, if you like doing things in Python, cryptography can help you extract the public key from the certificate:

from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend

certificate_text = open('certificate.cer', 'r').read()
certificate = load_pem_x509_certificate(certificate_text, default_backend())
publickey = certificate.public_key()

The publickey variable can then be passed in as the key to verify().

I hope that helps! I’m sorry I can’t help explain why you didn’t seem to run into this problem with v0.3.2 but it appears that the older version couldn’t import x509 certificates either.

Also, one last recommendation: most people consider 1024-bit RSA keys to be risky now as computers have gotten better and better at being able to brute-force them. Generally, most people have begun transitioning to 2048-bit (or higher) keys. Just something to consider. 😃

cc: @jpadilla

1reaction
wild3rcommented, Nov 22, 2016

from signxml import * from xml.etree import ElementTree import base64 from lxml import etree

Good day to all friends, I want to convert .pen to base64 and I sell the following error, thanks for the help

codigo:

Send File

f = open(‘/home/carlos/invoice/certifica/20600995805-01-FF11-00000027.xml’, ‘rb’) xml_content = f.read() cert = open(‘/home/carlos/invoice/certifica/CERTIFICADO.pem’).read() key = open(‘/home/carlos/invoice/certifica/CERTIFICADO.key’).read()

cert = base64.decodestring(cert) key = base64.b64decode(key)

error;

File “example.py”, line 14, in <module> cert = base64.decodestring(cert) File “/usr/lib/python2.7/base64.py”, line 321, in decodestring return binascii.a2b_base64(s) binascii.Error: Incorrect padding

Read more comments on GitHub >

github_iconTop Results From Across the Web

jwt RS256 signature verification failing · Issue #170 - GitHub
I am getting error in JWT RS256 signature verification because the PEM generated from n,e keys is invalid. jwt signature verification ...
Read more >
Signature verification failed, RSA signature did not verify - IBM
I've implemented a Web Service client with Spring-WS, and the requirement is to digitally sign the SOAP message and send the request to...
Read more >
Verifying JWT (RS256) using OpenSSL - Stack Overflow
The signature of a JWT is base64url encoded and needs to be decoded first. The suggested duplicate only deals with a base64 encoded...
Read more >
Navigating RS256 and JWKS - Auth0
Learn how to start using RS256 for signing and verifying your JWTs. ... If at least one signing key doesn't exist we have...
Read more >
Validating RSA signature for a JWS | by msingh - Medium
This article discusses validation of RSA signatures for a JWS. ... be digitally signed which is used to verify the integrity of claims...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found