<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ecommerce Ninja - The Zachary Fox Blog &#187; Ruby on Rails</title>
	<atom:link href="http://www.zacharyfox.com/blog/category/ruby-on-rails/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zacharyfox.com/blog</link>
	<description></description>
	<lastBuildDate>Fri, 18 Sep 2009 15:36:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ruby on Rails Password Hashing Module</title>
		<link>http://www.zacharyfox.com/blog/ruby-on-rails/password-hashing</link>
		<comments>http://www.zacharyfox.com/blog/ruby-on-rails/password-hashing#comments</comments>
		<pubDate>Sun, 14 Oct 2007 15:54:10 +0000</pubDate>
		<dc:creator>Zachary Fox</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.zacharyfox.com/blog/ruby-on-rails/password-hashing</guid>
		<description><![CDATA[This is a very simple password module that is also easy to use. Simpy place it in /lib inside your Ruby on Rails application and start protecting your passwords today. This code uses a long hash, and creates individual salts for each password stored. It should be very computationally expensive for someone to crack every [...]]]></description>
			<content:encoded><![CDATA[<p>This is a very simple password module that is also easy to use. Simpy place it in /lib inside your Ruby on Rails application and start protecting your passwords today. This code uses a long hash, and creates individual salts for each password stored. It should be very computationally expensive for someone to crack every password in your database, were they to fall into the wrong hands. Of course, if your database is in the wrong hands, you probably have bigger problems. But even some <a href="http://reddit.com/info/usqe/comments">large sites have been caught storing passwords in plain text</a>.</p>
<h2>Ruby Password Hashing Code</h2>
<p><!--adsense--></p>
<pre class="vci_code">
<span class="c31">require</span> <span class="c28">'</span><span class="c27">digest/sha2</span><span class="c28">'</span>

<span class="c26"># This module contains functions for hashing and storing passwords</span>
<span class="c31">module </span><span class="c32">Password</span>

  <span class="c26"># Generates a new salt and rehashes the password</span>
<span class="c31">  def </span><span class="c29">Password.update</span>(password)
    salt = <span class="c27">self</span>.salt
    hash = <span class="c27">self</span>.hash(password,salt)
    <span class="c27">self</span>.store(hash, salt)
  <span class="c31">end</span>

  <span class="c26"># Checks the password against the stored password</span>
<span class="c31">  def </span><span class="c29">Password.check</span>(password, store)
    hash = <span class="c27">self</span>.get_hash(store)
    salt = <span class="c27">self</span>.get_salt(store)
<span class="c30">    if</span> <span class="c27">self</span>.hash(password,salt) == hash
      <span class="c27">true</span>

    <span class="c30">else</span>
      <span class="c27">false</span>
    <span class="c30">end</span>
  <span class="c31">end</span>

  protected

  <span class="c26"># Generates a psuedo-random 64 character string</span>

<span class="c31">  def </span><span class="c29">Password.salt</span>
    salt = ..
    <span class="c27">64</span>.times { salt &lt;&lt; (i = <span class="c28">Kernel</span>.rand(<span class="c27">62</span>); i += ((i &lt; <span class="c27">10</span>) ? <span class="c27">48</span> : ((i &lt; <span class="c27">36</span>) ? <span class="c27">55</span> : <span class="c27">61</span> ))).chr }
    salt
  <span class="c31">end</span>

  <span class="c26"># Generates a 128 character hash</span>
<span class="c31">  def </span><span class="c29">Password.hash</span>(password,salt)
    <span class="c28">Digest</span>::<span class="c28">SHA512</span>.hexdigest(<span class="c28">&quot;</span><span class="c28">#{password}</span><span class="c27">:</span><span class="c28">#{salt}</span><span class="c28">&quot;</span>)
  <span class="c31">end</span>

  <span class="c26"># Mixes the hash and salt together for storage</span>
<span class="c31">  def </span><span class="c29">Password.store</span>(hash, salt)
    hash + salt
  <span class="c31">end</span>

  <span class="c26"># Gets the hash from a stored password</span>
<span class="c31">  def </span><span class="c29">Password.get_hash</span>(store)
    store[<span class="c27">0</span>..<span class="c27">127</span>]
  <span class="c31">end</span>

  <span class="c26"># Gets the salt from a stored password</span>
<span class="c31">  def </span><span class="c29">Password.get_salt</span>(store)
    store[<span class="c27">128..192</span>]
  <span class="c31">end</span>
<span class="c31">end</span>
</pre>
<p class="vci_info">HTML code generated by <a href="http://www.zacharyfox.com/blog/free-tools/vim-color-improved">vim-color-improved v.0.4.0.</a><strong>Download this code:</strong> <a href="http://www.zacharyfox.com/code/ruby/classes/password.rb">password.rb</a></p>
<h2>Usage</h2>
<p>Using the the password module is simple. All you need to do is save the file above as &#8220;password.rb&#8221; in the lib directory of your rails project. Then require_dependency &#8220;password&#8221; in your application.rb. Once that is done you are free to use the functions in any controller.</p>
<p class="main">&nbsp;</p>
<h2>Example</h2>
<h3>application.rb</h3>
<pre class="vci_code">
<span class="c26"># Filters added to this controller will be run for all controllers in the application.</span>
<span class="c26"># Likewise, all the methods added will be available for all controllers.</span>
require_dependency <span class="c28">'</span><span class="c27">password</span><span class="c28">'</span>

<span class="c31">class </span><span class="c32">ApplicationController </span>&lt; <span class="c28">ActionController</span>::<span class="c28">Base</span>
<span class="c31">end</span>
</pre>
<p class="vci_info">HTML code generated by <a href="http://www.zacharyfox.com/blog/free-tools/vim-color-improved">vim-color-improved v.0.4.0.</a><strong>Download this code:</strong> <a href="http://www.zacharyfox.com/code/ruby/examples/application.rb">application.rb</a></p>
<p><span style="color: #ff40ff"></span></p>
<h3>account_controller.rb</h3>
<p>This is an example account controller.</p>
<pre class="vci_code">
<span class="c31">class </span><span class="c32">AccountController </span>&lt; <span class="c28">ApplicationController</span>
  layout <span class="c28">'</span><span class="c27">standard</span><span class="c28">'</span>
  before_filter<span class="c28"> :login_required</span>,<span class="c28"> :except</span> =&gt; [:login]

<span class="c31">  def </span><span class="c29">login</span>
    <span class="c30">case</span> request.method
      <span class="c30">when</span><span class="c28"> :post</span>
<span class="c30">      if</span> session[:user] = <span class="c28">User</span>.authenticate(params[:user_login], params[:user_password])
        flash[:notice]  = <span class="c28">'</span><span class="c27">Login successful</span><span class="c28">'</span>

      <span class="c30">else</span>
        session[:user] = <span class="c27">nil</span>
        flash.now[:notice]  = <span class="c28">'</span><span class="c27">Login unsuccessful</span><span class="c28">'</span>
        <span class="c28">@login</span> = params[:user_login]
      <span class="c30">end</span>

    <span class="c30">end</span>
  <span class="c31">end</span>

<span class="c31">  def </span><span class="c29">logout</span>
    session[:user] = <span class="c27">nil</span>

  <span class="c31">end</span>

<span class="c31">  def </span><span class="c29">welcome</span>
  <span class="c31">end</span>

<span class="c31">end</span>
</pre>
<p class="vci_info">HTML code generated by <a href="http://www.zacharyfox.com/blog/free-tools/vim-color-improved">vim-color-improved v.0.4.0.</a><strong>Download this code:</strong> <a href="http://www.zacharyfox.com/code/ruby/examples/account_controller.rb">account_controller.rb</a></p>
<p><span style="color: #ff40ff"></span></p>
<h3>user.rb</h3>
<p>This is the model for the user class. As you can see, password checking against a hashed password is very simple here. Authenicating the user returns a User object, which is stored in the session[:user] variable in the controller above.</p>
<pre class="vci_code">
<span class="c31">class </span><span class="c32">User </span>&lt; <span class="c28">ActiveRecord</span>::<span class="c28">Base</span>

  <span class="c26"># Checks login information</span>
<span class="c31">  def </span><span class="c29">self.authenticate</span>(nick, pass)
    user = find(:first,<span class="c28"> :conditions</span> =&gt; [<span class="c28">'</span><span class="c27">nick = ?</span><span class="c28">'</span>,nick])

<span class="c30">    if</span> <span class="c28">Password</span>::check(pass,user.password)
      user
    <span class="c30">else</span>
      <span class="c30">return</span> <span class="c27">false</span>
    <span class="c30">end</span>
  <span class="c31">end</span>

  protected

  <span class="c26"># Hash the password before saving the record</span>
<span class="c31">  def </span><span class="c29">before_create</span>
    <span class="c27">self</span>.password = <span class="c28">Password</span>::update(<span class="c27">self</span>.password)
  <span class="c31">end</span>

<span class="c31">end</span>
</pre>
<p class="vci_info">HTML code generated by <a href="http://www.zacharyfox.com/blog/free-tools/vim-color-improved">vim-color-improved v.0.4.0.</a><strong>Download this code:</strong> <a href="http://www.zacharyfox.com/code/ruby/examples/user.rb">user.rb</a></p>
<p><span style="color: #ff40ff"></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zacharyfox.com/blog/ruby-on-rails/password-hashing/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
