def test(): key = ECKey(**JWK) ret_jwe = factory(maliciousJWE) jwdec = JWE_EC() with pytest.raises(ValueError): jwdec.dec_setup(ret_jwe.jwt, key=key.keys())
def test_signer_es256(): payload = "Please take a moment to register today" eck = ec.generate_private_key(ec.SECP256R1(), default_backend()) keys = [ECKey().load_key(eck)] _jws = JWS(payload, alg="ES256") _jwt = _jws.sign_compact(keys) _pubkey = ECKey().load_key(eck.public_key()) _rj = JWS() info = _rj.verify_compact(_jwt, [_pubkey]) assert info == payload
def test_verify_json_flattened_syntax(): key = ECKey().load_key(P256()) protected_headers = {"foo": "bar"} unprotected_headers = {"abc": "xyz"} payload = "hello world" _jwt = JWS(msg=payload, alg="ES256").sign_json( headers=[(protected_headers, unprotected_headers)], keys=[key], flatten=True) vkeys = [ECKey().load_key(key.key.public_key())] assert JWS().verify_json(_jwt, keys=vkeys)
def test_verify_json(): eck = ec.generate_private_key(ec.SECP256R1(), default_backend()) key = ECKey().load_key(eck) payload = "hello world" unprotected_headers = {"abc": "xyz"} protected_headers = {"foo": "bar"} _jwt = JWS(msg=payload, alg="ES256").sign_json( headers=[(protected_headers, unprotected_headers)], keys=[key]) vkeys = [ECKey().load_key(eck.public_key())] assert JWS().verify_json(_jwt, keys=vkeys)
def test_signer_es512(): payload = "Please take a moment to register today" eck = ec.generate_private_key(ec.SECP521R1(), default_backend()) _key = ECKey().load_key(eck) keys = [_key] # keys[0]._keytype = "private" _jws = JWS(payload, alg="ES512") _jwt = _jws.sign_compact(keys) _pubkey = ECKey().load_key(eck.public_key()) _rj = JWS() info = _rj.verify_compact(_jwt, [_pubkey]) assert info == payload
def test_cmp_rsa_ec(): _key1 = RSAKey() _key1.load_key(import_rsa_key_from_cert_file(CERT)) _key2 = ECKey(**ECKEY) assert _key1 != _key2
def test_sign_json_dont_flatten_if_multiple_signatures(): key = ECKey().load_key(P256()) unprotected_headers = {"foo": "bar"} _jwt = JWS(msg="hello world", alg="ES256").sign_json( headers=[(None, unprotected_headers), (None, {"abc": "xyz"})], keys=[key], flatten=True) assert "signatures" in json.loads(_jwt)
def test_sign_json_dont_include_empty_unprotected_headers(): key = ECKey().load_key(P256()) protected_headers = {"foo": "bar"} _jwt = JWS(msg="hello world", alg="ES256").sign_json( headers=[(protected_headers, None)], keys=[key]) json_jws = json.loads(_jwt) assert "header" not in json_jws["signatures"][0] jws_protected_headers = json.loads( b64d_enc_dec(json_jws["signatures"][0]["protected"])) assert set(protected_headers.items()).issubset( set(jws_protected_headers.items()))
def test_verify_protected_headers(): payload = "Please take a moment to register today" eck = ec.generate_private_key(ec.SECP256R1(), default_backend()) _key = ECKey().load_key(eck) keys = [_key] _jws = JWS(payload, alg="ES256") protected = dict(header1=u"header1 is protected", header2="header2 is protected too", a=1) _jwt = _jws.sign_compact(keys, protected=protected) protectedHeader, enc_payload, sig = _jwt.split(".") data = dict(payload=enc_payload, signatures=[ dict( header=dict(alg=u"ES256", jwk=_key.serialize()), protected=protectedHeader, signature=sig, ) ]) #_pub_key = ECKey().load_key(eck.public_key()) _jws = JWS() assert _jws.verify_json(json.dumps(data)) == payload
def test_signer_protected_headers(): payload = "Please take a moment to register today" eck = ec.generate_private_key(ec.SECP256R1(), default_backend()) _key = ECKey().load_key(eck) keys = [_key] _jws = JWS(payload, alg="ES256") protected = dict(header1=u"header1 is protected", header2="header2 is protected too", a=1) _jwt = _jws.sign_compact(keys, protected=protected) exp_protected = protected.copy() exp_protected['alg'] = 'ES256' enc_header, enc_payload, sig = _jwt.split('.') assert json.loads( b64d(enc_header.encode("utf-8")).decode("utf-8")) == exp_protected assert b64d(enc_payload.encode("utf-8")).decode("utf-8") == payload _pub_key = ECKey().load_key(eck.public_key()) _rj = JWS() info = _rj.verify_compact(_jwt, [_pub_key]) assert info == payload
def test_sign_json_dont_include_empty_protected_headers(): key = ECKey().load_key(P256()) unprotected_headers = {"foo": "bar"} _jwt = JWS(msg="hello world", alg="ES256").sign_json( headers=[(None, unprotected_headers)], keys=[key]) json_jws = json.loads(_jwt) jws_protected_headers = json.loads( b64d_enc_dec(json_jws["signatures"][0]["protected"])) assert jws_protected_headers == {"alg": "ES256"} jws_unprotected_headers = json_jws["signatures"][0]["header"] assert unprotected_headers == jws_unprotected_headers
def test_sign_json_flattened_syntax(): key = ECKey().load_key(P256()) protected_headers = {"foo": "bar"} unprotected_headers = {"abc": "xyz"} payload = "hello world" _jwt = JWS(msg=payload, alg="ES256").sign_json( headers=[(protected_headers, unprotected_headers)], keys=[key], flatten=True) json_jws = json.loads(_jwt) assert "signatures" not in json_jws assert b64d_enc_dec(json_jws["payload"]) == payload assert json_jws["header"] == unprotected_headers assert json.loads(b64d_enc_dec(json_jws["protected"])) == protected_headers
def test_sign_json(): eck = ec.generate_private_key(ec.SECP256R1(), default_backend()) key = ECKey().load_key(eck) payload = "hello world" unprotected_headers = {"abc": "xyz"} protected_headers = {"foo": "bar"} _jwt = JWS(msg=payload, alg="ES256").sign_json( headers=[(protected_headers, unprotected_headers)], keys=[key]) jwt = json.loads(_jwt) assert b64d_enc_dec(jwt["payload"]) == payload assert len(jwt["signatures"]) == 1 assert jwt["signatures"][0]["header"] == unprotected_headers assert json.loads( b64d_enc_dec(jwt["signatures"][0]["protected"])) == protected_headers
def dec_setup(self, token, key=None, **kwargs): """ :param token: signed JSON Web token :param key: Private Elliptic Curve Key :param kwargs: :return: """ self.headers = token.headers self.iv = token.initialization_vector() self.ctxt = token.ciphertext() self.tag = token.authentication_tag() # Handle EPK / Curve if "epk" not in self.headers or "crv" not in self.headers["epk"]: raise Exception( "Ephemeral Public Key Missing in ECDH-ES Computation") epubkey = ECKey(**self.headers["epk"]) apu = apv = "" if "apu" in self.headers: apu = b64d(self.headers["apu"].encode()) if "apv" in self.headers: apv = b64d(self.headers["apv"].encode()) if self.headers["alg"] == "ECDH-ES": try: dk_len = KEY_LEN[self.headers["enc"]] except KeyError: raise Exception("Unknown key length for algorithm") self.cek = ecdh_derive_key(key, epubkey.key, apu, apv, str(self.headers["enc"]).encode(), dk_len) elif self.headers["alg"] in ["ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]: _pre, _post = self.headers['alg'].split("+") klen = int(_post[1:4]) kek = ecdh_derive_key(key, epubkey.key, apu, apv, str(_post).encode(), klen) self.cek = aes_key_unwrap(kek, token.encrypted_key(), default_backend()) else: raise Exception("Unsupported algorithm %s" % self.headers["alg"]) return self.cek
def enc_setup(self, msg, key=None, auth_data=b'', **kwargs): """ :param msg: Message to be encrypted :param auth_data: :param key: An EC key :param kwargs: :return: """ encrypted_key = "" self.msg = msg self.auth_data = auth_data # Generate the input parameters try: apu = b64d(kwargs["apu"]) except KeyError: apu = get_random_bytes(16) try: apv = b64d(kwargs["apv"]) except KeyError: apv = get_random_bytes(16) # Handle Local Key and Ephemeral Public Key if not key: raise Exception("EC Key Required for ECDH-ES JWE Encryption Setup") # epk is either an Elliptic curve key instance or a JWK description of # one. This key belongs to the entity on the other side. try: _epk = kwargs['epk'] except KeyError: _epk = ec.generate_private_key(NIST2SEC[as_unicode(key.crv)], default_backend()) epk = ECKey().load_key(_epk.public_key()) else: if isinstance(_epk, ec.EllipticCurvePublicKey): epk = ECKey().load_key(_epk) elif isinstance(_epk, ECKey): epk = _epk else: raise ValueError("epk of a type I can't handle") params = { "apu": b64e(apu), "apv": b64e(apv), "epk": epk.serialize(False) } cek = iv = None if 'cek' in kwargs and kwargs['cek']: cek = kwargs['cek'] if 'iv' in kwargs and kwargs['iv']: iv = kwargs['iv'] iv = self._generate_iv(self.enc, iv=iv) if self.alg == "ECDH-ES": try: dk_len = KEY_LEN[self.enc] except KeyError: raise Exception( "Unknown key length for algorithm %s" % self.enc) cek = ecdh_derive_key(_epk, key.key, apu, apv, str(self.enc).encode(), dk_len) elif self.alg in ["ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]: _pre, _post = self.alg.split("+") klen = int(_post[1:4]) kek = ecdh_derive_key(_epk, key.key, apu, apv, str(_post).encode(), klen) cek = self._generate_key(self.enc, cek=cek) encrypted_key = aes_key_wrap(kek, cek, default_backend()) else: raise Exception("Unsupported algorithm %s" % self.alg) return cek, encrypted_key, iv, params, epk
assert msg == plain def test_rsa_with_kid(): encryption_keys = [RSAKey(use="enc", key=pub_key, kid="some-key-id")] jwe = JWE("some content", alg="RSA-OAEP", enc="A256CBC-HS512") jwe.encrypt(keys=encryption_keys, kid="some-key-id") if __name__ == "__main__": test_rsa_with_kid() # Test ECDH-ES alice = ec.generate_private_key(ec.SECP256R1(), default_backend()) eck_alice = ECKey(key=alice) bob = ec.generate_private_key(ec.SECP256R1(), default_backend()) eck_bob = ECKey(key=bob) def test_ecdh_encrypt_decrypt_direct_key(): # Alice starts of jwenc = JWE_EC(plain, alg="ECDH-ES", enc="A128GCM") cek, encrypted_key, iv, params, ret_epk = jwenc.enc_setup(plain, key=eck_bob) kwargs = { 'params': params, 'cek': cek, 'iv': iv, 'encrypted_key': encrypted_key
def test_is_jws_recognize_flattened_json_serialized_jws(): key = ECKey().load_key(P256()) jws = JWS(msg="hello world", alg="ES256").sign_json([key], flatten=True) assert JWS().is_jws(jws)
def test_is_jws_recognize_compact_jws(): key = ECKey().load_key(P256()) jws = JWS(msg="hello world", alg="ES256").sign_compact([key]) assert JWS().is_jws(jws)
def test_import_export_eckey(): _key = ECKey(**ECKEY) _key.deserialize() assert _eq(list(_key.keys()), ["y", "x", "d", "crv", "kty"])
def test_create_eckey(): ec_key = generate_private_key(NIST2SEC['P-256'], default_backend()) ec = ECKey(key=ec_key) exp_key = ec.serialize() assert _eq(list(exp_key.keys()), ["y", "x", "crv", "kty"])
def test_cmp_neq_ec(): ec_key = generate_private_key(NIST2SEC['P-256'], default_backend()) _key1 = ECKey(key=ec_key) _key2 = ECKey(**ECKEY) assert _key1 != _key2
def test_get_key(): ec_key = generate_private_key(NIST2SEC['P-256'], default_backend()) asym_private_key = ECKey(key=ec_key) asym_public_key = ECKey(key=asym_private_key.key.public_key()) sym_key = SYMKey(key='mekmitasdigoat', kid='xyzzy') asym_private_key.get_key(private=True) asym_private_key.get_key(private=False) with pytest.raises(ValueError): asym_public_key.get_key(private=True) asym_public_key.get_key(private=False) sym_key.get_key(private=True) sym_key.get_key(private=False)