def _timestamp(self, encrypted_data_bytes: bytes) -> int: if encrypted_data_bytes: timestamp, data = Fernet._get_unverified_token_data( encrypted_data_bytes) # pylint: disable=unused-variable return timestamp else: return 0
def test_rotate_preserves_timestamp(self, backend, monkeypatch): f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend) f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend) mf1 = MultiFernet([f1]) mf2 = MultiFernet([f2, f1]) plaintext = b"abc" mf1_ciphertext = mf1.encrypt(plaintext) later = datetime.datetime.now() + datetime.timedelta(minutes=5) later_time = time.mktime(later.timetuple()) monkeypatch.setattr(time, "time", lambda: later_time) original_time, _ = Fernet._get_unverified_token_data(mf1_ciphertext) rotated_time, _ = Fernet._get_unverified_token_data( mf2.rotate(mf1_ciphertext)) assert later_time != rotated_time assert original_time == rotated_time
def test_rotate_preserves_timestamp(self, backend, monkeypatch): f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend) f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend) mf1 = MultiFernet([f1]) mf2 = MultiFernet([f2, f1]) plaintext = b"abc" mf1_ciphertext = mf1.encrypt(plaintext) later = datetime.datetime.now() + datetime.timedelta(minutes=5) later_time = time.mktime(later.timetuple()) monkeypatch.setattr(time, "time", lambda: later_time) original_time, _ = Fernet._get_unverified_token_data(mf1_ciphertext) rotated_time, _ = Fernet._get_unverified_token_data( mf2.rotate(mf1_ciphertext) ) assert later_time != rotated_time assert original_time == rotated_time
def test_rotate_preserves_timestamp(self, backend, monkeypatch): f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend) f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend) mf1 = MultiFernet([f1]) mf2 = MultiFernet([f2, f1]) plaintext = b"abc" original_time = int(time.time()) - 5 * 60 mf1_ciphertext = mf1.encrypt_at_time(plaintext, original_time) rotated_time, _ = Fernet._get_unverified_token_data( mf2.rotate(mf1_ciphertext)) assert int(time.time()) != rotated_time assert original_time == rotated_time
def rotate_message(self, msg, force=False): """Re-encrypt a single message using the current primary key. The original timestamp included in the message is always preserved. Moreover the entire message is returned unchanged if it was already encrypted from the latest key and `force` is `False` (the default). `InvalidToken` is raised if decryption fails. """ timestamp, data = Fernet._get_unverified_token_data(msg) for i, fernet in enumerate(self.fernet._fernets): try: p = fernet._decrypt_data(data, timestamp, None) except InvalidToken: continue if i == 0 and not force: # This message was encrypted using the latest key, return it return msg break else: raise InvalidToken iv = os.urandom(16) return self.fernet._fernets[0]._encrypt_from_parts(p, timestamp, iv)
def validate_token(token: bytes): try: Fernet._get_unverified_token_data(token) # noqa return True except InvalidToken: return False
def verify(self, encrypted_data_bytes: bytes) -> None: "raise exception if metadata is invalid" if encrypted_data_bytes: Fernet._get_unverified_token_data(encrypted_data_bytes)