def generate( claims: dict, private_key_data: Optional[str] = None, algo: Optional[str] = None, headers: Optional[dict] = None, ) -> str: """Generates and returns a new JSON Web Token. :param dict claims: JWT claims set :param str private_key_data: Decoded RSA private key data. :param str algo: algorithm to be used. One of None, RS256, RS384 or RS512. :param dict headers: additional headers for the claim. :rtype: str """ # Allow for unencrypted JWTs if algo is not None: priv_key = PrivateKey(*private_key_data) else: algo = "none" # Create the JOSE Header # https://tools.ietf.org/html/rfc7519#section-5 jose_header = {"typ": "JWT", "alg": algo} if headers: jose_header.update(headers) payload = "{}.{}".format( STRING_TOOLS.urlsafe_b64encode(json.dumps(jose_header).encode("utf-8")), STRING_TOOLS.urlsafe_b64encode(json.dumps(claims).encode("utf-8")), ) # Compute the signature if algo == "none": jwt = "{}.{}".format(jose_header, claims) return jwt if algo == "RS256": signature = STRING_TOOLS.urlsafe_b64encode( sign(payload, priv_key, "SHA-256") ) elif algo == "RS384": signature = STRING_TOOLS.urlsafe_b64encode( sign(payload, priv_key, "SHA-384") ) elif algo == "RS512": signature = STRING_TOOLS.urlsafe_b64encode( sign(payload, priv_key, "SHA-512") ) else: raise TypeError( "Adafruit_JWT is currently only compatible with algorithms within" "the Adafruit_RSA module." ) jwt = payload + "." + signature return jwt
def test_sign_verify_sha512(): """Test SHA-512 sign and verify the message. """ (pub, priv) = adafruit_rsa.newkeys(752, log_level="DEBUG") msg = "red apple" signature = adafruit_rsa.sign(msg, priv, "SHA-512") adafruit_rsa.verify(msg, signature, pub)
def generate(claims, private_key_data=None, algo=None): """Generates and returns a new JSON Web Token. :param dict claims: JWT claims set :param str private_key_data: Decoded RSA private key data. :rtype: str """ # Allow for unencrypted JWTs if algo is not None: priv_key = PrivateKey(*private_key_data) # Create the JOSE Header # https://tools.ietf.org/html/rfc7519#section-5 jose_header = {"alg": algo, "type": "jwt"} # Encode the payload payload = "{}.{}".format( STRING_TOOLS.urlsafe_b64encode( json.dumps(jose_header).encode("utf-8")), STRING_TOOLS.urlsafe_b64encode(json.dumps(claims).encode("utf-8")), ) print(payload) # Compute the signature if algo is None: jwt = "{}.{}".format(jose_header, claims) elif (algo == "RS256" or algo == "RS384" or algo == "RS512" or algo == "RSA"): signature = STRING_TOOLS.urlsafe_b64encode( sign(payload, priv_key, "SHA-256")) jwt = "{}.{}".format(payload, signature) else: raise TypeError( "Adafruit_JWT is currently only compatible with algorithms within" "the Adafruit_RSA module.") return jwt
def test_sign_verify_fail(): """Check for adafruit_rsa.pkcs1.VerificationError on a modified message (invalid signature). """ # Generate general purpose keys (pub, priv) = adafruit_rsa.newkeys(256, log_level="DEBUG") msg = "red apple" signature = adafruit_rsa.sign(msg, priv, "SHA-512") msg = "blue apple" try: adafruit_rsa.verify(msg, signature, pub) except adafruit_rsa.pkcs1.VerificationError: # Expected error pass
import adafruit_rsa # Generate a keypair # # Supported Hash method Suggested minimum key size (bits) # SHA-256 496 # SHA-384 624 # SHA-512 752 # (public_key, private_key) = adafruit_rsa.newkeys(496) # Create a new secret message message = 'Meet me at 6pm' # Hash the message using SHA-224 hash_method = "SHA-256" signature = adafruit_rsa.sign(message, private_key, hash_method) # Verify Message Signature if adafruit_rsa.verify(message, signature, public_key) != hash_method: raise ValueError( "Verification failed - signature does not match secret message sent!")