Difference between revisions of "JWT"
imported>Jeremy-busk  | 
				|||
| Line 156: | Line 156: | ||
     data = get_some_data_by_user_id(user_id)  |      data = get_some_data_by_user_id(user_id)  | ||
     return json.dumps(data)  |      return json.dumps(data)  | ||
| + | ```  | ||
| + | |||
| + | |||
| + | ```  | ||
| + | ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key  | ||
| + | # Don't use passphrase  | ||
| + | openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub  | ||
| + | cat jwtRS256.key  | ||
| + | cat jwtRS256.key.pub  | ||
```  | ```  | ||
Latest revision as of 16:12, 21 March 2021
ECDSA SHA-512 pyjwt
import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend                                   
from cryptography.hazmat.primitives import hashes                                          
from cryptography.hazmat.primitives.asymmetric import ec    
private_key = ec.generate_private_key(        
    ec.SECP384R1(), default_backend()
)   
data = b"this is some data I'd like to sign"
signature = private_key.sign(
    data,
    ec.ECDSA(hashes.SHA256())
)
bytes_private_key = private_key.private_bytes(                                                  
    serialization.Encoding.PEM,                                                            
    serialization.PrivateFormat.PKCS8,                                                     
    serialization.NoEncryption())    
bytes_public_key = private_key.public_key().public_bytes(                                       
    serialization.Encoding.PEM,                                                           
    serialization.PublicFormat.SubjectPublicKeyInfo                                       
    )
a = b'{private_key_data}'
b = b'{public_key_data}'          
jwt_payload = {'iss': 'iss'}
ejwt = jwt.encode(jwt_payload, a, algorithm='ES512').decode('utf-8')
jwt.decode(ejwt, b, alogorithm='ES512')
View payload without verification
jwt.decode(jwt_token, verify=False) jwt.get_unverified_header(jwt_token)
# Other
openssl ec -in ecprivkey.pem -pubout -out ecpubkey.pem
import jwt
# ssh-keygen -f ecdsa_key -e -m PKCS8 > ecdsa_key.pub
private_key = open('ecdsa_key', 'r').read()
public_key = open('ecdsa_key.pub', 'r').read()
token = jwt.encode({ 'foo': 'bar' }, private_key, algorithm='ES256')
print(jwt.decode(token, public_key, algorithms=['ES256']))
New
https://blog.miguelgrinberg.com/post/json-web-tokens-with-public-key-signatures
https://stackoverflow.com/questions/29650495/how-to-verify-a-jwt-using-python-pyjwt-with-public-key
Overview of Operation
https://www.iana.org/assignments/jwt/jwt.xhtml#claims
https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec
https://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen
https://medium.com/@darutk/understanding-id-token-5f83f50fa02e
RFC & Wiki
https://tools.ietf.org/html/rfc7519
https://en.wikipedia.org/wiki/JSON_Web_Token#Standard_fields
Usage
https://blog.miguelgrinberg.com/post/json-web-tokens-with-public-key-signatures
pip3 install pyjwt
JWT_SECRET = 'secret'
encoded_jwt = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS512')
jwt.decode(encoded_jwt, 'secret') 
Refresh Tokens
- https://flask-jwt-extended.readthedocs.io/en/latest/refresh_tokens.html
 - https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
 
Resources
- https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec
 - https://developers.google.com/identity/toolkit/securetoken
 - https://pyjwt.readthedocs.io/en/latest/usage.html
 
Storage
Store as a Secure Cookie in browser and not in storage path
Example
From https://developers.google.com/identity/toolkit/securetoken
{
  "iss": "https://securetoken.google.com",
  "sub": "user_id"
  "aud": "project_id",
  "iat": issued_at,
  "exp": seconds_to_expiration,
  "email": "user_email"
}
Using Flask and PyJWT:
@app.route("/example_endpoint")
def example_endpoint():
    access_token = flask.headers["Authorization"]
    try:
        user_data = jwt.decode(access_token,
                               issuer="https://securetoken.google.com",
                               audience="exemplary-example-123456")
    except jwt.InvalidTokenError:
        return 401  # Invalid token
    except jwt.ExpiredSignatureError:
        return 401  # Token has expired
    except jwt.InvalidIssuerError:
        return 401  # Token is not issued by Google
    except jwt.InvalidAudienceError:
        return 401  # Token is not valid for this endpoint
    user_id = user_data["sub"]
    data = get_some_data_by_user_id(user_id)
    return json.dumps(data)
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key # Don't use passphrase openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub cat jwtRS256.key cat jwtRS256.key.pub