def test_aesgcm_bit_length(): encrypter = AES_GCMEncrypter(bit_length=192) enc_msg = encrypter.encrypt(b'Murder must advertise.', b'Dorothy L. Sayers') ctx, tag = split_ctx_and_tag(enc_msg) _msg = encrypter.decrypt(ctx, iv=b'Dorothy L. Sayers', tag=tag) assert _msg == b'Murder must advertise.'
def test_aesgcm_missing_iv_on_decrypt(): encrypter = AES_GCMEncrypter(bit_length=192) enc_msg = encrypter.encrypt(b'Murder must advertise.', b'Dorothy L. Sayers') ctx, tag = split_ctx_and_tag(enc_msg) with pytest.raises(ValueError): encrypter.decrypt(ctx, tag=tag)
def sign_enc_payload(load, timestamp=0, sign_key=None, enc_key=None, sign_alg="SHA256"): """ :param load: The basic information in the payload :param timestamp: A timestamp (seconds since epoch) :param sign_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param enc_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param sign_alg: Which signing algorithm to use :return: Signed and/or encrypted payload """ # Just sign, sign and encrypt or just encrypt if timestamp: timestamp = str(timestamp) else: timestamp = str(int(time.time())) bytes_load = load.encode("utf-8") bytes_timestamp = timestamp.encode("utf-8") if sign_key: signer = HMACSigner(algorithm=sign_alg) mac = signer.sign(bytes_load + bytes_timestamp, sign_key.key) else: mac = b"" if enc_key: if len(enc_key.key) not in [16, 24, 32]: raise ValueError("Wrong size of enc_key") encrypter = AES_GCMEncrypter(key=enc_key.key) iv = os.urandom(12) if mac: msg = lv_pack(load, timestamp, base64.b64encode(mac).decode("utf-8")) else: msg = lv_pack(load, timestamp) enc_msg = encrypter.encrypt(msg.encode("utf-8"), iv) ctx, tag = split_ctx_and_tag(enc_msg) cookie_payload = [ bytes_timestamp, base64.b64encode(iv), base64.b64encode(ctx), base64.b64encode(tag), ] else: cookie_payload = [bytes_timestamp, bytes_load, base64.b64encode(mac)] return (b"|".join(cookie_payload)).decode("utf-8")
def ver_dec_content(parts, sign_key=None, enc_key=None, sign_alg="SHA256"): """ Verifies the value of a cookie :param parts: The parts of the payload :param sign_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param enc_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param sign_alg: Which signing algorithm to was used :return: A tuple with basic information and a timestamp """ if parts is None: return None elif len(parts) == 3: # verify the cookie signature timestamp, load, b64_mac = parts mac = base64.b64decode(b64_mac) verifier = HMACSigner(algorithm=sign_alg) if verifier.verify( load.encode("utf-8") + timestamp.encode("utf-8"), mac, sign_key.key ): return load, timestamp else: raise VerificationError() elif len(parts) == 4: b_timestamp = parts[0] iv = base64.b64decode(parts[1]) ciphertext = base64.b64decode(parts[2]) tag = base64.b64decode(parts[3]) decrypter = AES_GCMEncrypter(key=enc_key.key) msg = decrypter.decrypt(ciphertext, iv, tag=tag) p = lv_unpack(msg.decode("utf-8")) load = p[0] timestamp = p[1] if len(p) == 3: verifier = HMACSigner(algorithm=sign_alg) if verifier.verify( load.encode("utf-8") + timestamp.encode("utf-8"), base64.b64decode(p[2]), sign_key.key, ): return load, timestamp else: return load, timestamp return None
def test_jwe_09_a1(): # RSAES OAEP and AES GCM msg = b"The true sign of intelligence is not knowledge but imagination." # A.1.1 header = b'{"alg":"RSA-OAEP","enc":"A256GCM"}' b64_header = b64e(header) # A.1.2 assert b64_header == b"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ" # A.1.3 cek = intarr2bytes([ 177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252 ]) # A.1.4 Key Encryption # enc_key = [ # 56, 163, 154, 192, 58, 53, 222, 4, 105, 218, 136, 218, 29, 94, 203, # 22, 150, 92, 129, 94, 211, 232, 53, 89, 41, 60, 138, 56, 196, 216, # 82, 98, 168, 76, 37, 73, 70, 7, 36, 8, 191, 100, 136, 196, 244, 220, # 145, 158, 138, 155, 4, 117, 141, 230, 199, 247, 173, 45, 182, 214, # 74, 177, 107, 211, 153, 11, 205, 196, 171, 226, 162, 128, 171, 182, # 13, 237, 239, 99, 193, 4, 91, 219, 121, 223, 107, 167, 61, 119, 228, # 173, 156, 137, 134, 200, 80, 219, 74, 253, 56, 185, 91, 177, 34, 158, # 89, 154, 205, 96, 55, 18, 138, 43, 96, 218, 215, 128, 124, 75, 138, # 243, 85, 25, 109, 117, 140, 26, 155, 249, 67, 167, 149, 231, 100, 6, # 41, 65, 214, 251, 232, 87, 72, 40, 182, 149, 154, 168, 31, 193, 126, # 215, 89, 28, 111, 219, 125, 182, 139, 235, 195, 197, 23, 234, 55, 58, # 63, 180, 68, 202, 206, 149, 75, 205, 248, 176, 67, 39, 178, 60, 98, # 193, 32, 238, 122, 96, 158, 222, 57, 183, 111, 210, 55, 188, 215, # 206, 180, 166, 150, 166, 106, 250, 55, 229, 72, 40, 69, 214, 216, # 104, 23, 40, 135, 212, 28, 127, 41, 80, 175, 174, 168, 115, 171, 197, # 89, 116, 92, 103, 246, 83, 216, 182, 176, 84, 37, 147, 35, 45, 219, # 172, 99, 226, 233, 73, 37, 124, 42, 72, 49, 242, 35, 127, 184, 134, # 117, 114, 135, 206] b64_ejek = b'ApfOLCaDbqs_JXPYy2I937v_xmrzj' \ b'-Iss1mG6NAHmeJViM6j2l0MHvfseIdHVyU2BIoGVu9ohvkkWiRq5DL2jYZTPA9TAdwq3FUIVyoH-Pedf6elHIVFi2KGDEspYMtQARMMSBcS7pslx6flh1Cfh3GBKysztVMEhZ_maFkm4PYVCsJsvq6Ct3fg2CJPOs0X1DHuxZKoIGIqcbeK4XEO5a0h5TAuJObKdfO0dKwfNSSbpu5sFrpRFwV2FTTYoqF4zI46N9-_hMIznlEpftRXhScEJuZ9HG8C8CHB1WRZ_J48PleqdhF4o7fB5J1wFqUXBtbtuGJ_A2Xe6AEhrlzCOw' iv = intarr2bytes([227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]) aadp = b64_header + b'.' + b64_ejek gcm = AES_GCMEncrypter(key=cek) ctxt, tag = split_ctx_and_tag(gcm.encrypt(msg, iv, aadp)) _va = to_intarr(ctxt) assert _va == [ 229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122, 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111, 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32, 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205, 160, 109, 64, 63, 192 ] assert bytes2intarr(tag) == [ 130, 17, 32, 198, 120, 167, 144, 113, 0, 50, 158, 49, 102, 208, 118, 152 ] # tag = long2hexseq(tag) # iv = long2hexseq(iv) res = b".".join([b64_header, b64_ejek, b64e(iv), b64e(ctxt), b64e(tag)]) # print(res.split(b'.')) expected = b'.'.join([ b'eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ', b'ApfOLCaDbqs_JXPYy2I937v_xmrzj' b'-Iss1mG6NAHmeJViM6j2l0MHvfseIdHVyU2BIoGVu9ohvkkWiRq5DL2jYZTPA9TAdwq3FUIVyoH-Pedf6elHIVFi2KGDEspYMtQARMMSBcS7pslx6flh1Cfh3GBKysztVMEhZ_maFkm4PYVCsJsvq6Ct3fg2CJPOs0X1DHuxZKoIGIqcbeK4XEO5a0h5TAuJObKdfO0dKwfNSSbpu5sFrpRFwV2FTTYoqF4zI46N9-_hMIznlEpftRXhScEJuZ9HG8C8CHB1WRZ_J48PleqdhF4o7fB5J1wFqUXBtbtuGJ_A2Xe6AEhrlzCOw', b'48V1_ALb6US04U3b', b'5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A', b'ghEgxninkHEAMp4xZtB2mA' ]) assert res == expected
def test_aesgcm_missing_iv_on_encrypt(): encrypter = AES_GCMEncrypter(bit_length=192) with pytest.raises(ValueError): encrypter.encrypt(b'Murder must advertise.')
def test_aesgcm_no_key_or_bit_length(): with pytest.raises(ValueError): AES_GCMEncrypter()
def test_aesgcm_unsupported_bit_length(): with pytest.raises(UnsupportedBitLength): AES_GCMEncrypter(bit_length=164)
def _encrypt_sid(self, sid): encrypter = AES_GCMEncrypter(key=as_bytes(self.server_get("endpoint_context").symkey)) enc_msg = encrypter.encrypt(as_bytes(sid), iv=self.iv) return as_unicode(b64e(enc_msg))
def _decrypt_sid(self, enc_msg): _msg = b64d(as_bytes(enc_msg)) encrypter = AES_GCMEncrypter(key=as_bytes(self.server_get("endpoint_context").symkey)) ctx, tag = split_ctx_and_tag(_msg) return as_unicode(encrypter.decrypt(as_bytes(ctx), iv=self.iv, tag=as_bytes(tag)))