# Terminal
openssl genrsa -out rsa_1024_priv.pem 1024
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
You will want to avoid storing the public and private keys in application.rb. Instead, you should have them in your secrets.yml, environment variable, parameter store or elsewhere secure.
# application.rb
PUBLIC_KEY = <PUBLIC KEY DATA>
PRIVATE_KEY = <PUBLIC KEY DATA>
# application.js
//= require jsencrypt
# application.js
$(document).on('turbolinks:load', function(){
$('form').submit(function( event ) {
var encrypt = new JSEncrypt();
$('[data-encrypt]').each(function(){
unencrypted = $(this);
encrypt.setKey($('#public_key').val());
encrypted = encrypt.encrypt(unencrypted.val());
if (encrypted != false) {
unencrypted.val(encrypted);
}
})
// event.preventDefault();
});
});
# users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
# POST /resource/sign_in
def create
# self.resource = warden.authenticate!(auth_options)
resource = User.find_by(email: params[:user][:email])
if resource&.valid_password?(authenticate_encryptor)
set_flash_message!(:notice, :signed_in)
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
else
redirect_to new_user_session_path, alert: 'Bad email or password.'
end
end
private
def authenticate_encryptor
private_key = OpenSSL::PKey::RSA.new(PRIVATE_KEY)
password = params[:user][:password]
private_key.private_decrypt(Base64.decode64(password))
end
end
# views/devise/sessions/new.html.erb
<%= f.password_field :password, autocomplete: "off", placeholder: 'Password', class: 'form-control', data: { encrypt: true } %>