10

I'm writing a little webapp that demonstrates 2 factor authentication. I'm using the TOTP protocol as described in RFC 6238. In our scheme, we are storing, in addition to a b-crypted password hash for each user, a secret key, which is used to validate one-time codes.

I'm using postgreSQL for a database backend. Let's pretend my database is compromised without my knowledge. The passwords are all safe since I'm salting and bcrypting them: there is no easy attack that will reveal all of the passwords, short of brute forcing each one.

Is there any way I can safely store the key for the TOTP though? I can't hash it, I need its plaintext for OTP validation.

Is there any way to securely store this key?

Wug
  • 293
  • 3
  • 8

1 Answers1

4

Yes. Encrypt the plain-text TOTP key on the application side and save the cipher-text into the database. If you cannot trust the application either, use a HSM (hardware security module) or create and use a software version of it.

Matrix
  • 3,988
  • 14
  • 25
  • Can you clarify? What exactly do you propose to use as the encryption key? How would the server store this key somehow (since it has to be able to verify the client's OTPs) – Wug Mar 02 '14 at 10:00
  • If you have a HSM, you store the symmetric key inside of it, same goes for software version (SSM) of it. Without HSM, you can store the key inside the application, like in a separate file, application config file, environment variable or fetch it from some other service using API at application startup. HSM will generate the key for you inside the device itself. In software, you can use openssl_* functions or read 32 bytes (256-bits) from /dev/urandom. – Matrix Mar 03 '14 at 06:53
  • 1
    That still involves storing everything I'd need to decrypt the SSK where the server can get at it, which would allow an attacker who compromised the database to get at them too. – Wug Mar 04 '14 at 08:15
  • Having access to the database service does not equal having full access to the underlying server. If you use a MAC like SELinux, you can severely restrict what an attacker can do with a compromised (database) service. You can prevent all file access outside of files needed for normal DB operation, you can prevent execution of all binaries, prevent all network (and local IPC) communication expect the one between the DB binary and some binary at a remote host (application). – Matrix Mar 05 '14 at 07:11