**Why**:
To provide an additional layer of security.
The TOTP spec (RFC 6238) recommends encrypting the keys.
http://tools.ietf.org/html/rfc6238
**How**:
Borrow the encryption code from the `attr_encrypted` gem and use it to
encrypt and decrypt the `otp_secret_key` attribute.
Allow users to add encryption by passing in `encrypted: true` to
`has_one_time_password`. This provides backwards-compatibility for
existing users of the gem.
See the README updates for more detailed instructions for both new
and existing users.
this will disable two factor authentication for local users
In the example above, two factor authentication will not be required for local
users.
This gem is compatible with Google Authenticator (https://support.google.com/accounts/answer/1066447?hl=en). You can generate provisioning uris by invoking the following method on your model:
This gem is compatible with [Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en).
You can generate provisioning uris by invoking the following method on your model:
user.provisioning_uri #This assumes a user model with an email attributes
```ruby
user.provisioning_uri # This assumes a user model with an email attribute
```
This provisioning uri can then be turned in to a QR code if desired so that users may add the app to Google Authenticator easily. Once this is done they may retrieve a one-time password directly from the Google Authenticator app as well as through whatever method you define in `send_two_factor_authentication_code`
This provisioning uri can then be turned in to a QR code if desired so that
users may add the app to Google Authenticator easily. Once this is done, they
may retrieve a one-time password directly from the Google Authenticator app as
well as through whatever method you define in
`send_two_factor_authentication_code`.
#### Overriding the view
The default view that shows the form can be overridden by first adding a folder named: "two_factor_authentication" inside "app/views/devise", in here you want to create a "show.html.erb" view.
The default view that shows the form can be overridden by adding a
file named `show.html.erb` (or `show.html.haml` if you prefer HAML)
inside `app/views/devise/two_factor_authentication/` and customizing it.
Below is an example using ERB:
The full path should be "app/views/devise/two_factor_authentication/show.html.erb"
```html
<h2>Hi, you received a code by email, please enter it below, thanks!</h2>
@ -125,21 +145,94 @@ The full path should be "app/views/devise/two_factor_authentication/show.html.er
#### Updating existing users with OTP secret key
If you have existing users that needs to be provided with a OTP secret key, so they can take benefit of the two factor authentication, create a rake. It could look like this one below:
If you have existing users that need to be provided with a OTP secret key, so
they can use two factor authentication, create a rake task. It could look like this one below:
```ruby
desc "rake task to update users with otp secret key"
desc 'rake task to update users with otp secret key'
task :update_users_with_otp_secret_key => :environment do
users = User.all
users.each do |user|
key = ROTP::Base32.random_base32
user.update_attributes(:otp_secret_key => key)
user.save
puts "Rake[:update_users_with_otp_secret_key] => User '#{user.email}' OTP secret key set to '#{key}'"
User.find_each do |user|
user.otp_secret_key = ROTP::Base32.random_base32
user.save!
puts "Rake[:update_users_with_otp_secret_key] => OTP secret key set to '#{key}' for User '#{user.email}'"
end
end
```
Then run the task with `bundle exec rake update_users_with_otp_secret_key`
#### Adding the OTP encryption option to an existing app
If you've already been using this gem, and want to start encrypting the OTP
secret key in the database (recommended), you'll need to perform the following
steps:
1. Generate a migration to add the necessary columns to your model's table:
```
rails g migration AddEncryptionFieldsToUsers encrypted_otp_secret_key:string:index encrypted_otp_secret_key_iv:string encrypted_otp_secret_key_salt:string
```
Open your migration file (it will be in the `db/migrate` directory and will be
named something like `20151230163930_add_encryption_fields_to_users.rb`), and
add `unique: true` to the `add_index` line so that it looks like this: