Cifrar JSON Web Token con Flask


Este token esta cifrado (JWE), no esta firmado (JWS), se cifra con la clave publica del certificado que este punto final, (API REST) crea, la clave privada del certificado permanece siempre en el servidor.
- JWE, quien tenga la clave privada puede leer los datos
- JWS, quien tenga el token puede leer los datos
Entonces firmando el token(que este ejemplo no contempla), y luego cifrándolo tenemos un token mas seguro.
En este escenario (prototipo), se mantiene el mismo token(por usuario) por sesión, el nombre del token es un string aleatorio que no se repite, cada usuario autenticado tiene su token, criptografía de clave pública(asimétrica).
Encrypted Token
# JWCrypto
from jwcrypto import jwt, jwe, jwk
from jwcrypto.common import json_encode, json_decode
import json, os
@auth.route('/getToken', methods=['POST'])
def getToken():
user = db_session.query(userModel).filter_by(id = request.get_json().get("id")).first()
if user:
payload1 = {'id': user.id, 'email': user.email, 'role': user.role}
payload = str(payload1)
key = jwk.JWK.generate(kty='EC', crv='P-256')
public_key = key.export(private_key=False)
private_key = key.export(private_key=True)
# keys users
path = os.getcwd()+'/jwt/'+str(user.id)
os.makedirs(path, exist_ok=True)
b = bytes(private_key, 'utf-8')
token = path+'/'+request.get_json().get("user_session").split(".")[1]
with open(token, 'wb') as key_file:
key_file.write(b)
# encrypt with public_key
key_public = json.loads(public_key)
expkey = {
"y": key_public.get('y'),
"x": key_public.get('x'),
"crv": key_public.get('crv'),
"kty": key_public.get('kty')
}
key_object_public_key = jwk.JWK(**expkey)
protected_header = {
"typ": "JWE",
"alg": "ECDH-ES+A256KW",
"enc": "A256CBC-HS512",
"kid": "12",
}
jwetoken = jwe.JWE(payload.encode('utf-8'),recipient=key_object_public_key,protected=protected_header)
enc = jwetoken.serialize()
resp = jsonify({"auth": enc, "crt": request.get_json().get("user_session").split(".")[1]})
return resp, 200
else:
return 'Incorrect user', 401Decorador token_required, desciframos el token con la clave privada
def token_required(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
json_object = json.loads(kwargs["id"])
access_token = request.headers['Authorization']
token = access_token.split()[1]
jwe_data = token
try:
path = os.getcwd()+'/jwt/'+json_object["id"]
token = path+'/'+str(json_object["user_session"])
with open(token, "rb") as key_file:
key_data = key_file.read()
except:
logging.error(f"Error loading key file")
# Object private key
private_key = json.loads(key_data)
expkey = {
"y": private_key.get('y'),
"x": private_key.get('x'),
"crv": private_key.get('crv'),
"kty": private_key.get('kty'),
"d": private_key.get('d')
}
key = jwk.JWK(**expkey)
jwetoken = jwe.JWE()
try:
jwetoken.deserialize(jwe_data, key=key)
except:
logging.error(f"FAILED - Decryption failed")
return 'FAILED - Decryption failed', 403
payload = jwetoken.payload
return fn(*args, **kwargs)
return wrapperUtilizacion
class user(Resource):
# Get resource
#@admin_required
@token_required
def get(self, id):
...
Related Posts
Dockerizar una aplicación Next.JS con Nginx y PostgreSQL
2025-09-21 00:00:00

Entorno de desarrollo local con Next.js, Drizzle, Nginx y PostgreSQL
2025-09-21 00:00:00

Web blog Next.js 15
2025-11-23 00:00:00
Popular Category
Subscribe to receive future updates
Lorem ipsum dolor sited Sed ullam corper consectur adipiscing Mae ornare massa quis lectus.
No spam guaranteed, So please don’t send any spam mail.