def test_rsa_verify_should_return_true_for_test_vector(self): """ This test verifies that RSA PKCS v1.5 verification works with a known good signature and key. Reference: https://tools.ietf.org/html/rfc7520#section-4.1 """ signing_input = ensure_bytes( 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhb' 'XBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb' '3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdS' 'Bkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmU' 'geW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4' ) signature = base64url_decode(ensure_bytes( 'MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZop' 'dHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJ' 'K3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4' 'QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic' '1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogor' 'ee7vjbU5y18kDquDg' )) algo = RSAAlgorithm(RSAAlgorithm.SHA256) key = algo.prepare_key(load_rsa_pub_key()) result = algo.verify(signing_input, key, signature) assert result
def test_rsa_verify_should_return_true_for_test_vector(self): """ This test verifies that RSA PKCS v1.5 verification works with a known good signature and key. Reference: https://tools.ietf.org/html/rfc7520#section-4.1 """ signing_input = ensure_bytes( 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhb' 'XBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb' '3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdS' 'Bkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmU' 'geW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4') signature = base64url_decode( ensure_bytes( 'MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZop' 'dHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJ' 'K3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4' 'QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic' '1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogor' 'ee7vjbU5y18kDquDg')) algo = RSAAlgorithm(RSAAlgorithm.SHA256) key = algo.prepare_key(load_rsa_pub_key()) result = algo.verify(signing_input, key, signature) assert result
def test_rsa_public_key_to_jwk_works_with_from_jwk(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.pub")) as rsa_key: orig_key = algo.prepare_key(rsa_key.read()) parsed_key = algo.from_jwk(algo.to_jwk(orig_key)) assert parsed_key.public_numbers() == orig_key.public_numbers()
def test_rsa_private_key_to_jwk_works_with_from_jwk(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa'), 'r') as rsa_key: orig_key = algo.prepare_key(force_unicode(rsa_key.read())) parsed_key = algo.from_jwk(algo.to_jwk(orig_key)) assert parsed_key.private_numbers() == orig_key.private_numbers() assert parsed_key.private_numbers().public_numbers == orig_key.private_numbers().public_numbers
def test_rsa_to_jwk_returns_correct_values_for_private_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.priv")) as keyfile: priv_key = algo.prepare_key(keyfile.read()) key = algo.to_jwk(priv_key) expected = { "key_ops": ["sign"], "kty": "RSA", "e": "AQAB", "n": ( "1HgzBfJv2cOjQryCwe8NEelriOTNFWKZUivevUrRhlqcmZJdCvuCJRr-xCN-" "OmO8qwgJJR98feNujxVg-J9Ls3_UOA4HcF9nYH6aqVXELAE8Hk_ALvxi96ms" "1DDuAvQGaYZ-lANxlvxeQFOZSbjkz_9mh8aLeGKwqJLp3p-OhUBQpwvAUAPg" "82-OUtgTW3nSljjeFr14B8qAneGSc_wl0ni--1SRZUXFSovzcqQOkla3W27r" "rLfrD6LXgj_TsDs4vD1PnIm1zcVenKT7TfYI17bsG_O_Wecwz2Nl19pL7gDo" "sNruF3ogJWNq1Lyn_ijPQnkPLpZHyhvuiycYcI3DiQ" ), "d": ( "rfbs8AWdB1RkLJRlC51LukrAvYl5UfU1TE6XRa4o-DTg2-03OXLNEMyVpMr" "a47weEnu14StypzC8qXL7vxXOyd30SSFTffLfleaTg-qxgMZSDw-Fb_M-pU" "HMPMEDYG-lgGma4l4fd1yTX2ATtoUo9BVOQgWS1LMZqi0ASEOkUfzlBgL04" "UoaLhPSuDdLygdlDzgruVPnec0t1uOEObmrcWIkhwU2CGQzeLtuzX6OVgPh" "k7xcnjbDurTTVpWH0R0gbZ5ukmQ2P-YuCX8T9iWNMGjPNSkb7h02s2Oe9ZR" "zP007xQ0VF-Z7xyLuxk6ASmoX1S39ujSbk2WF0eXNPRgFwQ" ), "q": ( "47hlW2f1ARuWYJf9Dl6MieXjdj2dGx9PL2UH0unVzJYInd56nqXNPrQrc5k" "ZU65KApC9n9oKUwIxuqwAAbh8oGNEQDqnuTj-powCkdC6bwA8KH1Y-wotpq" "_GSjxkNzjWRm2GArJSzZc6Fb8EuObOrAavKJ285-zMPCEfus1WZG0" ), "p": ( "7tr0z929Lp4OHIRJjIKM_rDrWMPtRgnV-51pgWsN6qdpDzns_PgFwrHcoyY" "sWIO-4yCdVWPxFOgEZ8xXTM_uwOe4VEmdZhw55Tx7axYZtmZYZbO_RIP4CG" "mlJlOFTiYnxpr-2Cx6kIeQmd-hf7fA3tL018aEzwYMbFMcnAGnEg0" ), "qi": ( "djo95mB0LVYikNPa-NgyDwLotLqrueb9IviMmn6zKHCwiOXReqXDX9slB8" "RA15uv56bmN04O__NyVFcgJ2ef169GZHiRFIgIy0Pl8LYkMhCYKKhyqM7g" "xN-SqGqDTKDC22j00S7jcvCaa1qadn1qbdfukZ4NXv7E2d_LO0Y2Kkc" ), "dp": ( "tgZ2-tJpEdWxu1m1EzeKa644LHVjpTRptk7H0LDc8i6SieADEuWQvkb9df" "fpY6tDFaQNQr3fQ6dtdAztmsP7l1b_ynwvT1nDZUcqZvl4ruBgDWFmKbjI" "lOCt0v9jX6MEPP5xqBx9axdkw18BnGtUuHrbzHSlUX-yh_rumpVH1SE" ), "dq": ( "xxCIuhD0YlWFbUcwFgGdBWcLIm_WCMGj7SB6aGu1VDTLr4Wu10TFWM0TNu" "hc9YPker2gpj5qzAmdAzwcfWSSvXpJTYR43jfulBTMoj8-2o3wCM0anclW" "AuKhin-kc4mh9ssDXRQZwlMymZP0QtaxUDw_nlfVrUCZgO7L1_ZsUTk" ), } assert json.loads(key) == expected
def generate_signed_data(payload, private_pem: str) -> str: """Generates signature for payload. :param payload: The payload to sign. :type payload: str|dict :param private_pem: The private key used for signing. :type private_pem: str :return: The signature. :rtype: str """ payload_string = get_signature_payload(payload) alg_obj = RSAAlgorithm(RSAAlgorithm.SHA256) key = alg_obj.prepare_key(private_pem) return alg_obj.sign(payload_string.encode('utf-8'), key)
def validate_signed_data(payload, signature: str, public_pem: str) -> bool: """Validates a signature for given payload. :param payload: The payload to validate. :type payload: str|dict :param signature: The signature to validate. :type signature: str :param public_pem: The public key used for validating. :type public_pem: str :return: True if signature valid, False otherwise. :rtype: bool """ payload_string = get_signature_payload(payload) alg_obj = RSAAlgorithm(RSAAlgorithm.SHA256) key = alg_obj.prepare_key(public_pem) return alg_obj.verify(payload_string.encode('utf-8'), key, signature)
def test_rsa_verify_should_return_true_if_signature_valid(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) jwt_message = ensure_bytes('Hello World!') jwt_sig = base64.b64decode(ensure_bytes( 'yS6zk9DBkuGTtcBzLUzSpo9gGJxJFOGvUqN01iLhWHrzBQ9ZEz3+Ae38AXp' '10RWwscp42ySC85Z6zoN67yGkLNWnfmCZSEv+xqELGEvBJvciOKsrhiObUl' '2mveSc1oeO/2ujkGDkkkJ2epn0YliacVjZF5+/uDmImUfAAj8lzjnHlzYix' 'sn5jGz1H07jYYbi9diixN8IUhXeTafwFg02IcONhum29V40Wu6O5tAKWlJX' 'fHJnNUzAEUOXS0WahHVb57D30pcgIji9z923q90p5c7E2cU8V+E1qe8NdCA' 'APCDzZZ9zQ/dgcMVaBrGrgimrcLbPjueOKFgSO+SSjIElKA==')) with open(key_path('testkey_rsa.pub'), 'r') as keyfile: jwt_pub_key = algo.prepare_key(keyfile.read()) result = algo.verify(jwt_message, jwt_pub_key, jwt_sig) self.assertTrue(result)
def test_rsa_verify_should_return_false_if_signature_invalid(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) message = b"Hello World!" sig = base64.b64decode( b"yS6zk9DBkuGTtcBzLUzSpo9gGJxJFOGvUqN01iLhWHrzBQ9ZEz3+Ae38AXp" b"10RWwscp42ySC85Z6zoN67yGkLNWnfmCZSEv+xqELGEvBJvciOKsrhiObUl" b"2mveSc1oeO/2ujkGDkkkJ2epn0YliacVjZF5+/uDmImUfAAj8lzjnHlzYix" b"sn5jGz1H07jYYbi9diixN8IUhXeTafwFg02IcONhum29V40Wu6O5tAKWlJX" b"fHJnNUzAEUOXS0WahHVb57D30pcgIji9z923q90p5c7E2cU8V+E1qe8NdCA" b"APCDzZZ9zQ/dgcMVaBrGrgimrcLbPjueOKFgSO+SSjIElKA==") sig += b"123" # Signature is now invalid with open(key_path("testkey_rsa.pub")) as keyfile: pub_key = algo.prepare_key(keyfile.read()) result = algo.verify(message, pub_key, sig) assert not result
def get(self, request, *args, **kwargs): """ jwks_uri view (http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata) """ certs = get_certs_jwks() rsa256 = RSAAlgorithm(RSAAlgorithm.SHA256) keys = [] for pub_key in get_public_keys(): key_obj = rsa256.prepare_key(pub_key.value) key = json.loads(RSAAlgorithm.to_jwk(key_obj)) key["kid"] = pub_key.component.uuid.hex key["alg"] = pub_key.component.name key["use"] = "sig" if pub_key.component.uuid.hex in certs: key.update(certs[pub_key.component.uuid.hex]) keys.append(key) data = {'keys': keys} return JsonHttpResponse(data, request, allow_jsonp=True, public_cors=True)
def test_rsa_to_jwk_returns_correct_values_for_public_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.pub")) as keyfile: pub_key = algo.prepare_key(keyfile.read()) key = algo.to_jwk(pub_key) expected = { "e": "AQAB", "key_ops": ["verify"], "kty": "RSA", "n": ( "1HgzBfJv2cOjQryCwe8NEelriOTNFWKZUivevUrRhlqcmZJdCvuCJRr-xCN-" "OmO8qwgJJR98feNujxVg-J9Ls3_UOA4HcF9nYH6aqVXELAE8Hk_ALvxi96ms" "1DDuAvQGaYZ-lANxlvxeQFOZSbjkz_9mh8aLeGKwqJLp3p-OhUBQpwvAUAPg" "82-OUtgTW3nSljjeFr14B8qAneGSc_wl0ni--1SRZUXFSovzcqQOkla3W27r" "rLfrD6LXgj_TsDs4vD1PnIm1zcVenKT7TfYI17bsG_O_Wecwz2Nl19pL7gDo" "sNruF3ogJWNq1Lyn_ijPQnkPLpZHyhvuiycYcI3DiQ" ), } assert json.loads(key) == expected
def test_rsa_to_jwk_returns_correct_values_for_public_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa.pub'), 'r') as keyfile: pub_key = algo.prepare_key(keyfile.read()) key = algo.to_jwk(pub_key) expected = { 'e': 'AQAB', 'key_ops': ['verify'], 'kty': 'RSA', 'n': ( '1HgzBfJv2cOjQryCwe8NEelriOTNFWKZUivevUrRhlqcmZJdCvuCJRr-xCN-' 'OmO8qwgJJR98feNujxVg-J9Ls3_UOA4HcF9nYH6aqVXELAE8Hk_ALvxi96ms' '1DDuAvQGaYZ-lANxlvxeQFOZSbjkz_9mh8aLeGKwqJLp3p-OhUBQpwvAUAPg' '82-OUtgTW3nSljjeFr14B8qAneGSc_wl0ni--1SRZUXFSovzcqQOkla3W27r' 'rLfrD6LXgj_TsDs4vD1PnIm1zcVenKT7TfYI17bsG_O_Wecwz2Nl19pL7gDo' 'sNruF3ogJWNq1Lyn_ijPQnkPLpZHyhvuiycYcI3DiQ' ), } assert json.loads(key) == expected
def test_rsa_should_accept_unicode_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa'), 'r') as rsa_key: algo.prepare_key(ensure_unicode(rsa_key.read()))
def test_rsa_should_parse_pem_public_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey2_rsa.pub.pem'), 'r') as pem_key: algo.prepare_key(pem_key.read())
def test_rsa_should_reject_non_string_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with pytest.raises(TypeError): algo.prepare_key(None)
def test_rsa_should_accept_unicode_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa'), 'r') as rsa_key: algo.prepare_key(ensure_unicode(rsa_key.read()))
def test_rsa_should_parse_pem_public_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey2_rsa.pub.pem'), 'r') as pem_key: algo.prepare_key(pem_key.read())
def test_rsa_should_reject_non_string_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with self.assertRaises(TypeError): algo.prepare_key(None)
def test_rsa_should_accept_unicode_key(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.priv")) as rsa_key: algo.prepare_key(rsa_key.read())
def test_rsa_should_accept_pem_private_key_bytes(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path("testkey_rsa.priv"), "rb") as pem_key: algo.prepare_key(pem_key.read())
def test_rsa_should_accept_pem_private_key_bytes(self): algo = RSAAlgorithm(RSAAlgorithm.SHA256) with open(key_path('testkey_rsa'), 'rb') as pem_key: algo.prepare_key(pem_key.read())