Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add basic encryption to password?

I'm creating a basic sign up form using ruby on rails (I'm relatively new to rails), and what I want to know is how can I encrypt the new user's password (for obvious security reasons)?

Here's my registration page:

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script type="text/javascript">
  $.noConflict();
  jQuery(document).ready(function($) {
    $('a.close').click(function(){
      $(this).parent().fadeOut();
    });
  });
</script>
<% if !flash.now[:notice].blank? %>
<div class="alert-message error">
  <a class="close" href="#">×</a>
  <p><strong><%= flash.now[:notice][0] %></strong></p>
</div>
<% end %>
<div class="alert-message info">
  <p><strong>Join us. It's as simple as 1 2 3.</strong></p>
</div>
<% form_for :user do |f| %>
  <p> Email: <br />  <%= f.text_field :email %></p>
  <p> Name: <br />  <%= f.text_field :name %></p>
  <p> Username:<br /><%= f.text_field :username %></p>
  <p> Password: <br />  <%= f.password_field :password %></p>
  <p> Blog <i>(optional)</i>: <br />  <%= f.text_field :blog %></p>
  <p><%= submit_tag "Create User", :disable_with => "Please wait...", :class => "btn primary" %></p>
<% end %>

And the User controller:

class UsersController < ApplicationController   
  def register
    @user = User.new(params[:user])
    if(request.post? and @user.save)
      flash[:notice] = "Account Created Successfully"
      redirect_to root_path      
    else
      flash.now[:notice] = @user.errors.full_messages
    end
  end
  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to root_path
  end  
end

Any help would be appreciated. Thanks in advance.

like image 643
Sam Avatar asked Aug 28 '11 08:08

Sam


3 Answers

Here you go:

self.salt = ActiveSupport::SecureRandom.base64(8)
self.hashed_password = Digest::SHA2.hexdigest(self.salt + submitted_password)

And the for the authentication:

def password_correct?
  user.hashed_password == Digest::SHA2.hexdigest(user.salt + password_to_confirm)
end

But like allesklar wrote, Rails 3.1 will be a good choice. Watch the Railscasts on the subject.

like image 61
Houen Avatar answered Oct 18 '22 22:10

Houen


You don't actually encrypt a user's password, you hash it.

Use a SHA2 hash, like SHA-256 or SHA-512. Incorporate a salt and stretching for added security against offline attacks. I can't do Ruby, but here is some pseudocode.

salt <- generateRandomSalt();

method hashPassword(password)
  hash <- password
  reps <- 5000  // Tune this number to your system
  for (reps times)
    hash <- hash + salt  // Concatenate
    hash <- SHA256(hash)
  end for
  return hash
end hashPassword

Store the final hash and the associated salt in your database for that user. Next time the user logs on repeat the process, using the same salt, and compare the final hashes. If they match the user entered the correct password.

Salting is used to make sure that if two users happen to pick the same password then their hashes are different. 64 to 128 bits (8 to 16 bytes) of salt is reasonable. Stretching (the 5000 repetitions) is to slow down an attacker. Pick the number of repetitions so it takes about 0.1 second to hash a password. A tenth of a second delay won't be noticed by a user logging on, but it will limit any attacker to trying at most ten guesses per second.

like image 21
rossum Avatar answered Oct 18 '22 22:10

rossum


If you are new, but not only, you might find it much easier to upgrade to Rails 3.1 and use the "has_secure_password" call in your model. There is a good post here.

All the work is done for you by Rails.

Edit: Changed link url according to Brian May's suggestion. Thanks Brian.

like image 2
allesklar Avatar answered Oct 18 '22 23:10

allesklar