Houdini / two_factor_authentication

Two factor authentication extension for Devise
MIT License
400 stars 268 forks source link

Explanation of fields #146

Open ArchieJG opened 6 years ago

ArchieJG commented 6 years ago

I'm in the process of implementing this gem but I'm slightly unclear as to what some of the fields are for, would it be possible to explain what they each are for, when they're set etc. If you reply to this issue I'd be happy to update the README for you and open a PR

second_factor_attempts_count
encrypted_otp_secret_key
encrypted_otp_secret_key_iv
encrypted_otp_secret_key_salt
direct_otp
direct_otp_sent_at
totp_timestamp

Thanks in advance

gencer commented 6 years ago

@ArchieJG let me explain all:

# How many times user tried to login with code? (sign in clicks) Sets each time user click the button and sent POST data.
second_factor_attempts_count

# This is our encrypted OTP key. You know we need a key to generate nmumbers. This is it. But its encrypted. Safer!. Sets during save!
encrypted_otp_secret_key

# This is IV part of encrypted key above. We also have key that declared in devise.rb. Sets during save!
encrypted_otp_secret_key_iv

# And salt of the key. Still need IV and our encryption key to work. Without three, enc/dec won't be possible. Sets during save!
encrypted_otp_secret_key_salt

# If TFA required AND keys are not initiated yet (above keys not set); we can send SMS for example with one time password. This is it. This is set on user login & tfa enabled & tfa key not exists.
direct_otp

# when we've sent/created one time code? This is set after user sign in.
direct_otp_sent_at

# When this TOTP generated? This is set when TOTP first generated.
totp_timestamp

Now, encrypted_otp_secret_key, encrypted_otp_secret_salt, encrypted_otp_secret_iv is created when you do this:

user...
user.otp_secret_key =  user.generate_totp_secret
user.save!

Now this gem will populate all necessary fields based on otp_secret_key. README does not mention about how encrypted fields sets. This is how. When you set user's otp_secret_key field, we emit it and reflect to encrypted fields.

What If you did not enable encrypted version? Then only plain text key will be stored. (Not safe!) Otherwise, it will be emitted and encrypted. All done in background.

UPDATE: How do I get decrypted key?

Simple. Call puts current_user.otp_secret_key

Tectract commented 6 years ago

This info should be added to the readme for sure!

How do I get the current 6-digit OTP code for a given user via the rails console? Is there a specific function to test a given 6-digit code for pass-fail?

Nevermind, found it, this is useful for a Google Auth setup page, to check if the user has the right codes being displayed on their phone before saving the user model with the encrypted key/salt.

current_user.authenticate_totp('123456')

Tectract commented 6 years ago

Actually, for the QR generation and confirmation step on setting up Google Auth for new users, it seems like I need another DB field to indicate whether the QR has been confirmed by the user on the setup page for the first time...