-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Description
I have an application in scope of FIPS that needs to validate JWT tokens of type RS256
. My best guess is that the jwt
is trying to use a low level API that OpenSSL disables when running in FIPS mode. I'm reporting here because I couldn't find another API in cryptography
for verifying an RSA signature.
RS256
is RSA with PKCS#1 v1.5 padding and SHA256. I believe this should be FIPS compliant --- the public key in the test below has a 4096-bit modulus. The test also fails with PS256
, which is RSA-PSS.
I'm on ARM64 and am building the OpenSSL 3.1.2 FIPS module. My backend is:
(.venv) root@4ea79d5dcc51:/w# OPENSSL_CONF=fips.cnf python
Python 3.13.5 (main, Jun 25 2025, 18:55:22) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cryptography.hazmat.backends import default_backend
>>> default_backend()
<OpenSSLBackend(version: OpenSSL 3.5.3 16 Sep 2025, FIPS: True, Legacy: True)>
Thanks in advance for any help!
Steps to reproduce
Jump into a container
docker run --rm -it -v "$PWD:/w" -w /w debian:trixie
Start virtual environment, install prerequisites
apt update && apt install -y openssl python3 python3-venv vim wget build-essential
python3 -m venv .venv && source .venv/bin/activate
pip install PyJWT cryptography
Install FIPS module
As described here.
wget https://www.openssl.org/source/openssl-3.1.2.tar.gz
tar -xf openssl-3.1.2.tar.gz
cd openssl-3.1.2
./Configure enable-fips
make
make install_fips
Control test
python test.py # expect success
Expected output:
(.venv) root@4ea79d5dcc51:/w# python test.py
FIPS: False
success
Test with FIPS enabled
OPENSSL_CONF=fips.cnf python test.py # expect ES256 success, but RS256 failure
Expected output:
(.venv) root@4ea79d5dcc51:/w# OPENSSL_CONF=fips.cnf python test.py
FIPS: True
RS256 failed:
Unknown OpenSSL error. This error is commonly encountered
when another library is not cleaning up the OpenSSL error
stack. If you are using cryptography with another library
that uses OpenSSL try disabling it before reporting a bug.
Otherwise please file an issue at
https://github.com/pyca/cryptography/issues with
information on how to reproduce this. (error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:375:Global default library context, Algorithm (SHA256 : 102), Properties (), error:03000086:digital envelope routines:evp_md_init_internal:initialization error:crypto/evp/digest.c:271:)
test.py
from cryptography.exceptions import InvalidSignature, InternalError
from cryptography.hazmat.backends.openssl.backend import backend
from jwt.algorithms import get_default_algorithms
print('FIPS:', backend._fips_enabled)
failures = 0
verifier = get_default_algorithms()["ES256"]
pk = verifier.from_jwk({
"kty":"EC",
"crv":"P-256",
"x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
"use":"sig",
"kid":"1",
})
try:
verifier.verify(b"some message", pk, b"invalid signature")
except InvalidSignature:
pass # We don't have a valid signature, so expect this to fail.
except InternalError as e:
print('ES256 failed:')
print(e)
failures += 1
verifier = get_default_algorithms()["RS256"]
pk = verifier.from_jwk({
"kty": "RSA",
"n": "tHbYl75dwWTcdrRBODUipsQ7qFfF7uGHGnP0eYI33dk0OW3lG_qh09dyPHQUeEXlcHBoWf-K08ofpl0jhequ5vvvN92PU-wL0qYNMXk2FCtLneUM8FzDEyLoKG_mMsrU-qnwvlw83vqdp9FPa8Ja2ImPooma_amsr3oW7vYhFYhr4R7F5Ph9CgIO4Lu8zkl1ZzqRdlIRkpjW-IDVKZlPZ2alNJlTUiqeS3rOdNn8y5ez9EUOreUhfsS8m39FbrJvNQEsA0DHeuVnIG_eDmKZ928HCcJh2CNOL4gY2cD9qoWOYx4e3RHUaXQn_p6MEmjxql4vL6-K99oOQYDN6ZdDr7gjHiSen7D5PZQtzJohIZBEqTEU2yLh8U8vQPqP5OqCx87hwwEqoHc80SLY4qSQhJOf1CayuuZQsBie3Sp21SsGXLLr9jCNPogKGbmOmpWaspXRdpFr6ep_DUpi3-qFO4_xBUkKj_08GsBW9sDj8btyhI2Wygc7n8D_PyQy8cWOc4we8E2xQ8mJwIevVE0--HoIy-M8QxdBly5igZalbOUx-qoPMOOdi07JA5o13HbTjdJA68XCBB3mWsqaiufGbjLlHaZ-tRnL1VNWopDHwLkIQmIFkGtpkt9aivMiRsnNK3pzg420rfOqbeCeWEl3mXYM_9v0BezbQg2OKlbn9Xc",
"e": "AQAB"
})
try:
verifier.verify(b"some message", pk, b"invalid signature")
except InvalidSignature:
pass # We don't have a valid signature, so expect this to fail.
except InternalError as e:
print('RS256 failed:')
print(e)
failures += 1
if failures == 0:
print('success')
fips.cnf
config_diagnostics = 1
openssl_conf = openssl_init
.include /usr/local/ssl/fipsmodule.cnf
[openssl_init]
providers = provider_sect
alg_section = algorithm_sect
[provider_sect]
fips = fips_sect
base = base_sect
[base_sect]
activate = 1
[algorithm_sect]
default_properties = fips=yes
Metadata
Metadata
Assignees
Labels
No labels