def validate_signature(signed_mf): """ Validate the signature of a signed manifest A signed manifest is a JSON document with a signature attribute as the last element. """ # In order to validate the signature, we need the exact original payload # (the document without the signature). We cannot json.load the document # and get rid of the signature, the payload would likely end up # differently because of differences in field ordering and indentation. # So we need to strip the signature using plain string manipulation, and # add back a trailing } # strip the signature block payload, sep, signatures = signed_mf.partition(' "signatures"') # get rid of the trailing ,\n, and add \n} jw_payload = payload[:-2] + '\n}' # base64-encode and remove any trailing = jw_payload = base64.urlsafe_b64encode( jw_payload.encode('ascii')).decode('ascii').rstrip("=") # add payload as a json attribute, and then add the signatures back complete_msg = payload + ' "payload": "{}",\n'.format( jw_payload) + sep + signatures _jws = jws.JWS() _jws.verify_json(complete_msg.encode('ascii'))
def _decode_and_verify(): jwt_claims = jwt.JWT().unpack(auth_token).payload() _verify_required_claims_exist(jwt_claims) issuer = jwt_claims["iss"] keys = self._jwks_supplier.supply(issuer) try: return jws.JWS().verify_compact(auth_token, keys) except (jwkest.BadSignature, jws.NoSuitableSigningKeys, jws.SignerAlgError) as exception: raise suppliers.UnauthenticatedException( "Signature verification failed", exception)
def sign(data, key): """ Sign the JSON data with the passed key. """ now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z" header = dict(alg="ES256", jwk=key.serialize()) protected = dict(formatLength=len(data) - 2, formatTail=jws.b64encode_item(data[-2:]), time=now) _jws = jws.JWS(data, **header) protectedHeader, payload, signature = _jws.sign_compact([key], protected=protected).split(".") signatures = [dict(header=header, signature=signature, protected=protectedHeader)] jsig = _jsonDumps(dict(signatures=signatures))[1:-2] arr = [data[:-2], ",", jsig, data[-2:]] # Add the signature block at the end of the json string, keeping the formatting data_with_signature = "".join(arr) return data_with_signature
def sign(data, key): """ Sign the JSON document with a elliptic curve key """ jdata = _jsonDumps(data) now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + 'Z' header = dict(alg="ES256", jwk=key.serialize()) protected = dict(formatLength=len(jdata) - 2, formatTail=jws.b64encode_item(jdata[-2:]), time=now) _jws = jws.JWS(jdata, **header) protectedHeader, payload, signature = _jws.sign_compact([key], protected=protected).split(".") signatures = [dict(header=header, signature=signature, protected=protectedHeader)] jsig = _jsonDumps(dict(signatures=signatures))[1:-2] arr = [jdata[:-2], ',', jsig, jdata[-2:]] # Add the signature block at the end of the json string, keeping the # formatting jdata2 = ''.join(arr) return jdata2
def generate_auth_token(payload, keys, alg=u"ES256", kid=None): json_web_signature = jws.JWS(json.dumps(payload), alg=alg, kid=kid) return json_web_signature.sign_compact(keys=keys)