'Everyone' knows when storing passwords in a database this should be done securely for example by using salts and an appropriate hashing algorithm.

Most OTP (One Time Password) solutions are based on a long secret random seed value. Somehow this needs to be stored at the validating server as well to be able to verify the submitted OTP value.

In a way these seeds have the same role as user supplied passwords and need to be stored equally secure. Salting & hashing will not work here as this will break the OTP algorithm.
Most small OTP-tokens are physically secured by being more or less tamper-proof but this does not apply to the server.

How can the seeds be stored in a proper way?

And if there is a solution for storing the seeds without hashing, why not apply the same method to regular passwords?

3 Answers 3


Roughly speaking, the best you can do is to harden the server to make it as resistant to compromise as possible.

Ideally, you would store the seed in a hardware security module (HSM; aka a crypto co-processor). You'd make sure the seed never leaves the HSM, i.e., do all cryptographic computations in the HSM. This offers better protection, though it is admittedly more expensive.

But, as you correctly point out, you cannot store the seed in hashed form. The seed must be stored in the clear, so if that server gets compromised, you are in big trouble. This means it is absolutely vital that you protect that server just as well as you are able to.

OTP seeds are different from passwords. People tend to use the same password on multiple sites; that doesn't happen with OTP seeds. Hashing passwords is used partly to protect users' passwords, so that if site X's database is breached, then X's users' accounts on other sites aren't compromised. That threat simply doesn't apply to OTP seeds.

Also, with passwords, you can hash passwords. If you can, you might as well, since it does help mitigate some risks. (And passwords are so widely used, and used by developers who are not security experts, that it is a near given that many sites who use passwords will experience a security breach at some point.) Since you can't hash OTP seeds, this mitigation simply isn't available for OTP seeds — so you'll have to use other methods to protect your OTP seeds. Fortunately, only very security-aware sites should be storing their own OTP seeds, so if one is optimistic, one might hope that they are in a better position to apply other defenses.

Anyway, since OTP seeds have different characteristics from passwords, you shouldn't assume that every mitigation for passwords will necessarily transfer over to OTP seeds as well.


You can encrypt the OTP seed using a symmetric key derived from user's password. However, this requires the user to enter the password before entering the OTP, otherwise the server cannot decrypt the OTP seed.

Alternatively, you could have a highly secure server that gets passed the encrypted OTP seed and returns a currently valid OTP. Symmetric key for seeds is stored on this server. HSM could also help you here.

  • 1
    This doesn't work in the event of a password reset since the user forgot their password, but you maybe be using the user's email address and a OTP to allow them to change their password.
    – John
    Commented Aug 16, 2016 at 19:35
  • 2
    If the user forgot their password, you should not use the username and OTP to authenticate--that effectively relegates you to one-factor authentication. Since you should be offering the user backup codes for MFA anyway, a better way would be to also store copies of the OTP secret encrypted with the backup codes. When the user with MFA enabled goes through the password reset process, they should provide one of the backup codes, which you can then use to retrieve the cleartext OTP secret and reset the password-encrypted secret. Commented Apr 27, 2018 at 14:24

Lets say you have a TOTP time range of 'T'. i.e. your OTP expires after T time. What can be done is (for all the users one by one) that if the user has not requested an OTP T time prior to the current time you can change the seed. As the user has not requested an otp in our time window we can be sure that there is no OTP which is yet to be authenticated by our server. So, in case the attacker gets the seed it, the seed would have changed.

  • 4
    That's not how TOTP works, you can't change the seed without invalidating the client's TOTP generator. Commented Nov 29, 2018 at 22:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .