'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?

2 Answers
2

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 ake 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 servergets compromised, you arein bigtrouble. 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.