Generating public/private RSA key pair programmatically, using it for JWTs In my app I'm using JSON Web Tokens for authentication purposes, using the pyjwt library. Instead of using static keys and/or worrying about key distribution, the server generates a public/private key pair upon startup itself and just keeps it in memory. The keys will be reset and thereby all existing tokens invalidated when the server restarts, which is fine for the intended use case. The key pair is generated using pycrypto.

The question is: am I generating and using the keys correctly, or is there any flaw which can lead to an exploit? Below is the general class which generates and validates all JWTs in my app:

from typing import NamedTuple
from datetime import datetime
import jwt
from Crypto.PublicKey import RSA

KeyPair = NamedTuple('KeyPair', [('public', str), ('private', str)])

class JWT:
    def __init__(self, keypair: KeyPair=None, algorithm: str='RS256'):
        self.keypair = keypair or self.generate_keypair()
        self.algorithm = algorithm

    @staticmethod
    def generate_keypair() -&gt; KeyPair:
        key = RSA.generate(2048)
        return KeyPair(public=key.publickey().exportKey('PEM').decode('ascii'),
                       private=key.exportKey('PEM').decode('ascii'))

    def generate_token(self, payload: dict) -&gt; str:
        payload.update(dict(iat=datetime.utcnow()))
        return jwt.encode(payload, key=self.keypair.private, algorithm=self.algorithm).decode('ascii')

    def decode_payload(self, token: str, **kwargs) -&gt; dict:
        try:
            return jwt.decode(token, self.keypair.public, algorithms=[self.algorithm], **kwargs)
        except jwt.exceptions.InvalidTokenError as e:
            raise InvalidAuthenticationToken
There isn't too much to see here because the key generation simply relies on RSA.generate(2048), but I wonder why you would need this code as it is exceedingly shallow.

Regenerating key pairs for signing at startup is utter nonsense because a key pair is next to useless if the public key isn't trusted by the receiving party.

Exporting the private key as unprotected PEM is also very dangerous. The method would fail if hardware support (a HSM) is ever used.

The inclusion of  payload.update(dict(iat=datetime.utcnow())) is undocumented. Although it may be expected for webtokens, a caller will want to know that this is performed. Undocumented side effects are a sure fire way of breaking the principle of least surprise.

Passing kwargs** without any validation doesn't give me a very warm feeling inside.

Slightly less of an issue maybe, but an RSA 2048 bit key provides a key strength of only 112 bits or so. You may want to consider at least 3072 bits.

This code is clearly related only to webtokens and RSA keys, even with a specific key size. So allowing an argument algorithm: str='RS256' may just allow a user to get the object instance in an invalid state, and not much more.