I’m very new to cryptography and I need to use a symmetric cryptography approach.

My simple question is, will the key always at any time be able to decrypt the encrypted text? The encrypted text may be years old, and key will be saved years before as well.

Is there any time factor applied that may make the decryption fail?


No, there is generally no time factor when it comes to decryption.

However, you should remember that even a single changed bit can cause decryption to fail. This is especially the case if that bit is part of the IV, authentication tag or nonce. So I'd rather worry about storage of keys and data. Disks may get stuck, flash may degrade or loose voltage differential.

  • $\begingroup$ This part "Fernet itself seems to allow you to set a TTL (time to live). However, this is checked by the Fernet implementation during decryption. If you leave it out the message should decrypt as normal. It's a choice up to the decrypting entity, not of the encrypting entity. The encryption entity will just set a time stamp to calculate the message age." relies too much on the answer by Alexander, so I've removed it. $\endgroup$ – Maarten Bodewes Aug 28 '20 at 16:35

TL;DR: The explanation in the article below is a little bit irritating but it seems to me that it's still possible to decrypt all messages at any time, as it is normal for any symmetric ciphers. You can decrypt the message, provided you have the necessary key.

As this article (PythonInformer) explains in section "Decrypting a message":

decrypt will raise an exception if it cannot decode token for any reason. For example:

  • The token is malformed, most likely because it has an invalid length, see later.
  • The HMAC signature doesn't match. This could because the key is incorrect or because the token has been modified after creation.
  • The token has expired.

Fernet tokens contain a timestamp which allows testing for an expired message. To do this you must add the a ttl (time to live) parameter to the decrypt function that specifies a maximum age (in seconds) of the token before it will be rejected. For example:

decoded = cipher.decrypt(token, 24*60*60) This will reject any messages that are more than 1 day old. If you do not set a ttl value (or set it to None), the age of the token will not be checked at all.


As a general rule, encryption does not depend on time that has passed. In fact, an algorithm which can "expire" a message such that it cannot be decrypted after a certain date is a holy grail of sorts. If memory serves, we've proven it is actually impossible for encryption to do this. Unless you deal with a physical effect like the "bit rot" described by Maarten Bodewes you cannot have a document that fails to decrypt after a certain time. If you want a Mission Impossible like message which self destructs after five seconds, you have to do it the Mission Impossible way: a physical layer. Encryption is all about information. If you have the information to decrypt a message, and you do not lose that information, you can still decrypt the message.

Software suites, on the other hand, can have things that expire. They just don't do so in a cryptographic sense. Instead they trust a clock, and can simply refuse to accept documents with a timestamp that is invalid based upon this trusted current time. Of course, this wont stop an attacker from simply setting their trusted clock to a valid time, and then reading your message.

The purpose of these timestamps is not to cause a message to fail to decrypt at a certain time, but to identify a "token" which expires. This prevents attacks like replay attacks, where an attacker gets their hands on your encrypted message and tries to use it as their own message. Consider a virtual ATM which you can sent a message to say "withdraw $100." You would like to avoid attackers being able to watch your message, and then replay it 5 or 6 times to get a few hundred dollars.

Thus this timestamp plays a part when interacting with a trusted party who will honor this token. If the attacker sends a message to the bank asking to withdraw $100, the bank will still decrypt the message, and it will still have your correct signature inside the message. However, the bank will note that the token is too old, and refuse the withdraw. It would ask you to sign a new message which is more current, something an adversary cannot do. But note that the message was indeed decryptable. The token just wasn't honored.

This is a very powerful feature for designing algorithms, just not related to making a message unencryptable. As an example, if I want to make sure my bank cannot be subject to a replay attack, one solution would be to only accept messages with a time-to-live of 10 seconds, and hold onto a history of all messages received in the last 10 seconds. When a new message comes in, I have to compare it against 10 seconds worth of message traffic to see if its the first time I've seen this message. After 10 seconds, I no longer need to keep it in my memory; even if I see it again, the token will be expired, so I will know to reject the replay on that front.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.