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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With