Digitally signing code requires a code-signing certificate. Only certificates issued by trusted Certificate Authorities (CAs) are accepted by default by the Java Runtime. For security reasons, certificates are only valid for a limited period, usually one to three years, from the time they are issued.
Although the signature itself doesn’t expire, for a digital signature to be considered valid, the signing must happen while the code-signing certificate is valid. Signatures created with expired certificates are not considered valid. It is important then to know when the signature was created. Unfortunately, we can’t simply trust the “file created” property in a file as that value can be faked.
One way to ensure that the signature was created while the code-signing certificate was valid is to accept only code signed with certificates that are still valid at the time of checking the signature. The problem with this approach is that one would need to re-sign and re-distribute the code about once a year even if the code itself hasn’t changed.
A better way of validating if a signature was created while a certificate was valid is to use time-stamping. Time-stamping requires that a trusted third party, the Time-Stamping Authority (TSA), confirm that a given signature was created on or before a given date. This time-stamp is added to the signed code as proof that signing was done before the code-signing certificate expired.
The point sometimes missed is that time-stamping itself is nothing more than another digital signature, using the time-stamping’s authority certificate rather than the developer’s code signing certificate, but still subject to the same rules and with its own expiration date to consider. Ideally the time-stamping authority uses a certificate that expires much further into the future than the code-signing certificate.
Once the time-stamping server’s certificate expires we will no longer be able to trust that the time-stamp was created when the certificate was valid. It will no longer be possible to confirm if the original signature was created before the code-signing certificate expired.
Time-stamping can greatly extend the valid lifetime of signed code, sometimes for long enough that the code is no longer used, but if signed code remains in use long enough it will eventually need to be re-signed.
Expiration dates are only one of the reasons why a signature may no longer be trusted. The certificates involved in code signing or time-stamping may be revoked if they are compromised, or the algorithms used for creating them may be cracked before the certificate expires. Anything that voids the code-signing certificate will affect the code’s signature. Anything that voids the time-stamping certificate will void the time-stamp.
One could believe that time-stamping services would always use certificates that will expire far into the future and sign only with algorithms and key-lengths believed to be valid for a long period but it is sometimes necessary, for backward compatibility, to time-stamp with algorithms that we suspect will be insecure in the medium term, and in those cases time-stamping authorities might choose to use time-stamping certificates with a shorter validity.
It is important that developers learn the pros and cons of each time-stamping services that they rely on, that they keep track of when their code’s signature will no longer be valid, and take steps to re-sign and re-distribute code with enough time to avoid disruptions.
If you want to get a more detailed understanding of how code signing and time-stamping work at a lower level please read Understanding Digital Certificates and Code Signing.