def test_jws_signature_mismatch_error(self): jwk = {'k': 'password'} jws = jose.sign(claims, jwk) try: jose.verify(jose.JWS(jws.header, jws.payload, 'asd'), jwk) except ValueError as e: self.assertEqual(e.message, 'Mismatched signatures')
def test_jws_signature_mismatch_error(self): jwk = {'k': 'password'} jws = jose.sign(claims, jwk) try: jose.verify(jose.JWS(jws.header, jws.payload, 'asd'), jwk) except jose.Error as e: self.assertEqual(e.message, 'Mismatched signatures')
def test_jws_invalid_algorithm_error(self): sign_alg = 'HS256' verify_alg = 'RS256' jwk = {'k': 'password'} jws = jose.sign(claims, jwk, alg=sign_alg) try: jose.verify(jose.JWS(jws.header, jws.payload, 'asd'), jwk, verify_alg) except jose.Error as e: self.assertEqual(e.message, 'Invalid algorithm')
def test_jws_asym(self): algs = ('RS256', 'RS384', 'RS512') for alg in algs: st = jose.serialize_compact(jose.sign(claims, rsa_priv_key, alg=alg)) jwt = jose.verify(jose.deserialize_compact(st), rsa_pub_key) self.assertEqual(jwt.claims, claims)
def test_get_freja_state(self): user = self.app.central_userdb.get_user_by_eppn(self.test_user_eppn) proofing_state = create_proofing_state(user, self.test_user_nin) self.app.proofing_statedb.save(proofing_state) with self.session_cookie(self.browser, self.test_user_eppn) as browser: response = json.loads(browser.get('/freja/proofing').data) self.assertEqual(response['type'], 'GET_OIDC_PROOFING_FREJA_PROOFING_SUCCESS') jwk = {'k': self.app.config['FREJA_JWK_SECRET'].decode('hex')} jwt = str(response['payload']['iaRequestData']) request_data = jose.verify(jose.deserialize_compact(jwt), jwk, alg=self.app.config['FREJA_JWS_ALGORITHM']) expected = { 'iarp': 'TESTRP', 'opaque': '1' + json.dumps({ 'nonce': proofing_state.nonce, 'token': proofing_state.token }), 'proto': u'1.0' } self.assertIn('exp', request_data.claims) self.assertEqual(request_data.claims['iarp'], expected['iarp']) self.assertEqual(request_data.claims['opaque'], expected['opaque']) self.assertEqual(request_data.claims['proto'], expected['proto'])
def _decrypt_and_verify(self, plaintext, decr_key, signing_key, alg = 'RS256'): jwe = jose.deserialize_compact(plaintext.replace("\n", '')) decrypted = jose.decrypt(jwe, decr_key) if not 'v1' in decrypted.claims: return False to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, signing_key, alg=alg) return jwt
def test_jws_sym(self): algs = ('HS256', 'HS384', 'HS512',) jwk = {'k': 'password'} for alg in algs: st = jose.serialize_compact(jose.sign(claims, jwk, alg=alg)) jwt = jose.verify(jose.deserialize_compact(st), jwk, alg) self.assertEqual(jwt.claims, claims)
def _decrypt_and_verify(self, plaintext, decr_key, signing_key, alg='RS256'): jwe = jose.deserialize_compact(plaintext.replace("\n", '')) decrypted = jose.decrypt(jwe, decr_key) if not 'v1' in decrypted.claims: return False to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, signing_key, alg=alg) return jwt
def decrypt_response(self, ciphertext=None, return_jwt=False): """ Decrypt the response returned from send_request. :param ciphertext: Ciphertext to decrypt. If not supplied the last request response is used. :param return_jwt: Return the whole JOSE JWT or just the claims :type ciphertext: None | str | unicode :type return_jwt: bool :return: Decrypted result :rtype: dict | jose.JWT """ if ciphertext is None: ciphertext = self._request_result.text jwe = jose.deserialize_compact(ciphertext.replace("\n", '')) priv_key = self._config.keys.private_key if not priv_key.keytype == 'jose': raise EduIDAPIError("Non-jose private key unusuable with decrypt_response") decrypted = jose.decrypt(jwe, priv_key.jwk) if not 'v1' in decrypted.claims: self._logger.error("No 'v1' in decrypted claims: {!r}\n\n".format(decrypted)) raise EduIDAPIError("No 'v1' in decrypted claims") to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, self._api_key.jwk, alg = self._config.jose_alg) self._logger.debug("Good signature on response to request using key: {!r}".format( self._api_key.jwk )) if 'nonce' in self._claims: # there was a nonce in the request, verify it is also present in the response if not 'nonce' in jwt.claims: self._logger.warning("Nonce was present in request, but not in response:\n{!r}".format( jwt.claims )) raise EduIDAPIError("Request-Response nonce validation error") if jwt.claims['nonce'] != self._claims['nonce']: self._logger.warning("Response nonce {!r} does not match expected {!r}".format( jwt.claims['nonce'], self._claims['nonce'] )) if return_jwt: return jwt return jwt.claims
def _verify(self, decrypted, remote_ip): """ verify a JOSE signed objecct. :param decrypted: Data to verify :param remote_ip: IP address of client :type decrypted: jose.JWS :type remote_ip: basestring :rtype: jose.JWT or False """ keys = self._config.keys.lookup_by_ip(remote_ip) if not len(keys): self._logger.info("No API keys found for IP address {!r}, can't verify signature".format(remote_ip)) return False # Now, check for a valid signature for key in keys: if not key.keytype == 'jose': self._logger.debug("Ignoring key {!r}".format(key)) continue try: jwt = jose.verify(decrypted, key.jwk, alg = self._config.jose_alg) self._logger.debug("Good signature on request from {!r} using key {!r}: {!r}".format( remote_ip, key, jwt )) self._signing_key = key return jwt except ValueError: self._logger.debug("Ignoring key unusable with this algorithm: {!r}".format(key)) pass except jose.Error as ex: self._logger.debug("Tried verifying signature using key {!r}: {!r}".format(key, ex)) pass self._logger.warning("Failed verifying signature on request from {!r} using keys {!r}".format( remote_ip, keys )) return False
MIICBjCCAW+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEN MAsGA1UEAxMEYXNkZjETMBEGCSqGSIb3DQEJARMEYXNkZjAeFw0xMzA4MjIyMTMx NTNaFw0xNDA4MjIyMTMxNTNaMDExCzAJBgNVBAYTAlVTMQ0wCwYDVQQDEwRhc2Rm MRMwEQYJKoZIhvcNAQkBEwRhc2RmMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQCZdrbHbZ87wBILsrQvJLB50Eg77XGzmvUUsI0eB+7Q+a4qhin1LfOwm1NdHYzY ZR/GSLPxJPl0Jni/sbCmA6Zf94Z/FHRJMBGPbcqCehF6GD1ECKOY9fGL37U9Ue7+ gbcwvm5nTmdkE9AlmCoZe8MJDJXDq3JeAqtaY9dvx4guawIDAQABoy4wLDAMBgNV HRMEBTADAQH/MAsGA1UdDwQEAwIC9DAPBgNVHREECDAGgQRhc2RmMA0GCSqGSIb3 DQEBBQUAA4GBACNbRRnq5utziHBiUAh7z87Mgm9EzsNOz/tYRqbiHYqNpHiYAaCV 0puGCKeB+kU/kIqFI0nQ4aWjZDQmtgPj39oI2EuzL0c+J3ux9NhiE5YIg2Bkrf2z f56W5ExLLyiBerztpkt430HoDmoK13wBr+nzEX8JIeD+KFvlcizUHEM0 """ payload = "Shall I compare the to a summer's day?" # Test sign / verify with jwk jws1 = jose.sign({"alg": "RS256", "jwk": jwk_pub}, [jwk_priv], payload) ver1 = jose.verify(jws1, []) print(jws1) print() print(ver1) print() # Test sign / verify with x5c jws2 = jose.sign({"alg": "RS256", "x5c": [cert]}, [jwk_priv], payload) ver2 = jose.verify(jws1, []) print(jws2) print() print(ver2) print()
from jose.util import b64enc # JWS ## A.1. HS256 key = { "kty":"oct", "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" } jws = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" jwsd = deserialize(jws) jwsb = serialize_msgpack(jwsd) ver = jose.verify(jwsb, [key]) print "HS256 {res} ({clen} / {blen} / {blen64})".format( res = ver["result"], clen = len(jws), blen = len(jwsb), blen64 = len(b64enc(jwsb))) ## A.2. RS256 key = { "kty":"RSA", "n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", "e":"AQAB", "d":"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ"
MIICBjCCAW+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVUzEN MAsGA1UEAxMEYXNkZjETMBEGCSqGSIb3DQEJARMEYXNkZjAeFw0xMzA4MjIyMTMx NTNaFw0xNDA4MjIyMTMxNTNaMDExCzAJBgNVBAYTAlVTMQ0wCwYDVQQDEwRhc2Rm MRMwEQYJKoZIhvcNAQkBEwRhc2RmMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQCZdrbHbZ87wBILsrQvJLB50Eg77XGzmvUUsI0eB+7Q+a4qhin1LfOwm1NdHYzY ZR/GSLPxJPl0Jni/sbCmA6Zf94Z/FHRJMBGPbcqCehF6GD1ECKOY9fGL37U9Ue7+ gbcwvm5nTmdkE9AlmCoZe8MJDJXDq3JeAqtaY9dvx4guawIDAQABoy4wLDAMBgNV HRMEBTADAQH/MAsGA1UdDwQEAwIC9DAPBgNVHREECDAGgQRhc2RmMA0GCSqGSIb3 DQEBBQUAA4GBACNbRRnq5utziHBiUAh7z87Mgm9EzsNOz/tYRqbiHYqNpHiYAaCV 0puGCKeB+kU/kIqFI0nQ4aWjZDQmtgPj39oI2EuzL0c+J3ux9NhiE5YIg2Bkrf2z f56W5ExLLyiBerztpkt430HoDmoK13wBr+nzEX8JIeD+KFvlcizUHEM0 """ payload = "Shall I compare the to a summer's day?" # Test sign / verify with jwk jws1 = jose.sign({ "alg":"RS256", "jwk": jwk_pub }, [jwk_priv], payload ) ver1 = jose.verify(jws1, []) print jws1 print print ver1 print # Test sign / verify with x5c jws2 = jose.sign({ "alg":"RS256", "x5c": [cert] }, [jwk_priv], payload ) ver2 = jose.verify(jws1, []) print jws2 print print ver2 print
# JWS ## A.1. HS256 key = { "kty": "oct", "k": "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" } jws = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" jwsd = deserialize(jws) jwsb = serialize_msgpack(jwsd) ver = jose.verify(jwsb, [key]) print "HS256 {res} ({clen} / {blen} / {blen64})".format(res=ver["result"], clen=len(jws), blen=len(jwsb), blen64=len( b64enc(jwsb))) ## A.2. RS256 key = { "kty": "RSA", "n": "ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", "e": "AQAB",
# Send token print "\t< Send Token >" print "\t |" print "\t+-------+ +-------+" print "\t| | | |" print "\t| BA +----- INTERNET (bad guys) -----> MtB |" print "\t| | | |" print "\t+-------+ +-------+" print "\t |" print "\t< Receive Token >" print "\t |" # Verify Token using public key external print "\t< Verify token signature (token, public external key) >" print "\t |" try: signed_jws = jose.verify(jose.deserialize_compact(jwt), jwk, 'HS256') print "\t OK" print "\t |" except: print "\tWrong token signature! " print "\tError signing token! " e = sys.exc_info()[0] print "Error: %s" % e exit() print "\t< Decrypt information (information, MtB private key) >" print "\t |" try: # JWT(header={u'alg': u'HS256'}, claims={u'iss': u'http://www.example.com', u'sub': 42, u'exp': 1395674427}) header = signed_jws[0] claims = signed_jws[1]
# key = b"""-----BEGIN PRIVATE KEY----- # MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgsegINAr5xcE48BiD # yfXjsfQmEk1ReGtD7bSuKsKx04CgCgYIKoZIzj0DAQehRANCAASauMCp36D8FOF1 # 5OGI1+fe5oeRoCbY5yGQ2Jk0Gi9P92ksyvC8LK7JDqtzKfEf18UsScYc+NWffEtt # v413G73q # -----END PRIVATE KEY-----""" # k = {'k': 'password'} # # signed = jws.sign(data, k, algorithm='ES256') # print(signed) # data = jws.verify(signed, k, algorithms='ES256') # print(data) jwk = {'k': 'password'} jws = jose.sign(data, jwk, alg='HS256') # JWS(header='eyJhbGciOiAiSFMyNTYifQ', # payload='eyJpc3MiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbSIsICJzdWIiOiA0MiwgImV4cCI6IDEzOTU2NzQ0Mjd9', # signature='WYApAiwiKd-eDClA1fg7XFrnfHzUTgrmdRQY4M19Vr8') # issue the compact serialized version to the clients. this is what will be # transported along with requests to target systems. jwt = jose.serialize_compact(jws) # 'eyJhbGciOiAiSFMyNTYifQ.eyJpc3MiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbSIsICJzdWIiOiA0MiwgImV4cCI6IDEzOTU2NzQ0Mjd9.WYApAiwiKd-eDClA1fg7XFrnfHzUTgrmdRQY4M19Vr8' jose.verify(jose.deserialize_compact(jwt), jwk, 'HS256') # JWT(header={u'alg': u'HS256'}, claims={u'iss': u'http://www.example.com', u'sub': 42, u'exp': 1395674427})
#!/usr/bin/env python import jose # JWS ## A.1. HS256 key = { "kty":"oct", "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" } jws = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" ver = jose.verify(jws, [key]) print "HS256 " + str(ver["result"]) ## A.2. RS256 key = { "kty":"RSA", "n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", "e":"AQAB", "d":"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ" } jws = "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqvhJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrBp0igcN_IoypGlUPQGe77Rw" ver = jose.verify(jws, [key])
# Encrypt into the JSON serialization jwe1 = jose.encrypt(jwe_header, keys, plaintext) dec1 = jose.decrypt(jwe1, keys) print jwe1 print dec1 print # Encrypt into the compact serialization jwe2 = serialize_compact( \ jose.encrypt(jwe_header, keys, plaintext, protect="*")) dec2 = jose.decrypt(jwe2, keys) print jwe2 print dec2 print # Sign into the JSON serialization jws1 = jose.sign(jws_header, keys, plaintext) ver1 = jose.verify(jws1, keys) print jws1 print ver1 print # Sign into the compact serialization jws2 = serialize_compact( \ jose.sign(jws_header, keys, plaintext, protect="*")) ver2 = jose.verify(jws2, keys) print jws2 print ver2 print
xdata = json.loads((b64ish + padding).decode('base64')) return xdata except: pass # padding error return None # # Retrieve description in the signed data # signeddata = json.loads(received) jws = jose.JWS(signeddata['header'], signeddata['payload'], signeddata['signature']) print 'JWS =', jws # print '_asdict is', jose.JWS (signeddata)._asdict () hdr = extractdata(signeddata['header']) print hdr, '::', type(hdr) for k in hdr.keys(): print k, 'is set to', hdr[k] print 'Signature age is', time.time() - hdr['timestamp'], 'seconds' # # Validate the signature # try: # jose.verify (signeddata, sharedkey) jose.verify(jws, sharedkey) print 'Signature correct' except Exception, e: print 'SIGNATURE BAD:', e
print print "Decrypted, decompressed JWE:" print dec1 print # Criticality test payload = "Some day you may pass validation. Today is not that day." jws_header1 = { "alg":"HS256", "crit": ["alg"] } jws_header2 = { "alg":"HS256", "true_rings": 1, "crit": ["true_rings"] } keys = [{ "kty":"oct", "k":"i-ueSNQgcr0q7auC8YUrYg" }] # Test 1: Should fail on sign try: jws1 = jose.sign(jws_header1, keys, payload) ver1 = jose.verify(jws1, keys) except Exception as e: print e print # Test 2: Should fail on verify try: jws2 = jose.sign(jws_header2, keys, payload) ver2 = jose.verify(jws2, keys) except Exception as e: print e print