<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Password Hashing — Botan</title> <link rel="stylesheet" href="_static/agogo.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: './', VERSION: '1.10.14', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> <link rel="top" title="Botan" href="index.html" /> <link rel="next" title="Random Number Generators" href="rng.html" /> <link rel="prev" title="PBKDF Algorithms" href="pbkdf.html" /> </head> <body> <div class="header-wrapper"> <div class="header"> <h1>Botan</h1> </div> </div> <div class="content-wrapper"> <div class="content"> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="password-hashing"> <h1>Password Hashing<a class="headerlink" href="#password-hashing" title="Permalink to this headline">¶</a></h1> <p>Storing passwords for user authentication purposes in plaintext is the simplest but least secure method; when an attacker compromises the database in which the passwords are stored, they immediately gain access to all of them. Often passwords are reused among multiple services or machines, meaning once a password to a single service is known an attacker has a substantial head start on attacking other machines.</p> <p>The general approach is to store, instead of the password, the output of a one way function of the password. Upon receiving an authentication request, the authenticator can recompute the one way function and compare the value just computed with the one that was stored. If they match, then the authentication request succeeds. But when an attacker gains access to the database, they only have the output of the one way function, not the original password.</p> <p>Common hash functions such as SHA-256 are one way, but used alone they have problems for this purpose. What an attacker can do, upon gaining access to such a stored password database, is hash common dictionary words and other possible passwords, storing them in a list. Then he can search through his list; if a stored hash and an entry in his list match, then he has found the password. Even worse, this can happen <em>offline</em>: an attacker can begin hashing common passwords days, months, or years before ever gaining access to the database. In addition, if two users choose the same password, the one way function output will be the same for both of them, which will be visible upon inspection of the database.</p> <p>There are two solutions to these problems: salting and iteration. Salting refers to including, along with the password, a randomly chosen value which perturbs the one way function. Salting can reduce the effectivness of offline dictionary generation (because for each potential password, an attacker would have to compute the one way function output for all possible salts - with a large enough salt, this can make the problem quite difficult). It also prevents the same password from producing the same output, as long as the salts do not collide. With a large salt (say 80 to 128 bits) this will be quite unlikely. Iteration refers to the general technique of forcing multiple one way function evaluations when computing the output, to slow down the operation. For instance if hashing a single password requires running SHA-256 100,000 times instead of just once, that will slow down user authentication by a factor of 100,000, but user authentication happens quite rarely, and usually there are more expensive operations that need to occur anyway (network and database I/O, etc). On the other hand, an attacker who is attempting to break a database full of stolen password hashes will be seriously inconvenienced by a factor of 100,000 slowdown; they will be able to only test at a rate of .0001% of what they would without iterations (or, equivalently, will require 100,000 times as many zombie botnet hosts).</p> <p>Botan provides two techniques for password hashing, bcrypt and passhash9.</p> <div class="section" id="bcrypt-password-hashing"> <span id="bcrypt"></span><h2>Bcrypt Password Hashing<a class="headerlink" href="#bcrypt-password-hashing" title="Permalink to this headline">¶</a></h2> <p>Bcrypt is a password hashing scheme originally designed for use in OpenBSD, but numerous other implementations exist. It is made available by including <tt class="docutils literal"><span class="pre">bcrypt.h</span></tt>. Bcrypt provides outputs that look like this:</p> <div class="highlight-cpp"><div class="highlight"><pre><span class="s">"$2a$12$7KIYdyv8Bp32WAvc.7YvI.wvRlyVn0HP/EhPmmOyMQA4YKxINO0p2"</span> </pre></div> </div> <dl class="function"> <dt id="generate_bcrypt__ssCR.RandomNumberGeneratorR.u16bit"> std::string <tt class="descname">generate_bcrypt</tt><big>(</big>const std::string& <em>password</em>, RandomNumberGenerator& <em>rng</em>, u16bit <em>work_factor</em><em>=10</em><big>)</big><a class="headerlink" href="#generate_bcrypt__ssCR.RandomNumberGeneratorR.u16bit" title="Permalink to this definition">¶</a></dt> <dd><p>Takes the password to hash, a rng, and a work factor. Higher values increase the amount of time the algorithm runs, increasing the cost of cracking attempts. The resulting hash is returned as a string.</p> </dd></dl> <dl class="function"> <dt id="check_bcrypt__ssCR.ssCR"> bool <tt class="descname">check_bcrypt</tt><big>(</big>const std::string& <em>password</em>, const std::string& <em>hash</em><big>)</big><a class="headerlink" href="#check_bcrypt__ssCR.ssCR" title="Permalink to this definition">¶</a></dt> <dd><p>Takes a password and a bcrypt output and returns true if the password is the same as the one that was used to generate the bcrypt hash.</p> </dd></dl> <p>Here is an example of using bcrypt:</p> <div class="highlight-cpp"><div class="highlight"><pre><span class="cp">#include <botan/botan.h></span> <span class="cp">#include <botan/bcrypt.h></span> <span class="cp">#include <iostream></span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">Botan</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span> <span class="p">{</span> <span class="k">if</span><span class="p">(</span><span class="n">argc</span> <span class="o">!=</span> <span class="mi">2</span> <span class="o">&&</span> <span class="n">argc</span> <span class="o">!=</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Usage: "</span> <span class="o"><<</span> <span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><<</span> <span class="s">" password</span><span class="se">\n</span><span class="s">"</span> <span class="o"><<</span> <span class="s">" "</span> <span class="o"><<</span> <span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><<</span> <span class="s">" password passhash</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="n">LibraryInitializer</span> <span class="n">init</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">argc</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="n">AutoSeeded_RNG</span> <span class="n">rng</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">generate_bcrypt</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">rng</span><span class="p">,</span> <span class="mi">12</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">argc</span> <span class="o">==</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span><span class="p">(</span><span class="n">strlen</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="o">!=</span> <span class="mi">60</span><span class="p">)</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Note: hash "</span> <span class="o"><<</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o"><<</span> <span class="s">" has wrong length and cannot be valid</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">const</span> <span class="kt">bool</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">check_bcrypt</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Password is "</span> <span class="o"><<</span> <span class="p">(</span><span class="n">ok</span> <span class="o">?</span> <span class="s">"valid"</span> <span class="o">:</span> <span class="s">"NOT valid"</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </pre></div> </div> </div> <div class="section" id="passhash9"> <span id="id1"></span><h2>Passhash9<a class="headerlink" href="#passhash9" title="Permalink to this headline">¶</a></h2> <p>Botan also provides a password hashing technique called passhash9, in <tt class="docutils literal"><span class="pre">passhash9.h</span></tt>, which is based on PBKDF2. Its outputs look like:</p> <div class="highlight-cpp"><div class="highlight"><pre><span class="s">"$9$AAAKxwMGNPSdPkOKJS07Xutm3+1Cr3ytmbnkjO6LjHzCMcMQXvcT"</span> </pre></div> </div> <dl class="function"> <dt id="generate_passhash9__ssCR.RandomNumberGeneratorR.u16bit.byte"> std::string <tt class="descname">generate_passhash9</tt><big>(</big>const std::string& <em>password</em>, RandomNumberGenerator& <em>rng</em>, u16bit <em>work_factor</em><em>=10</em>, byte <em>alg_id</em><em>=0</em><big>)</big><a class="headerlink" href="#generate_passhash9__ssCR.RandomNumberGeneratorR.u16bit.byte" title="Permalink to this definition">¶</a></dt> <dd><p>Functions much like <tt class="docutils literal"><span class="pre">generate_bcrypt</span></tt>. The last parameter, <tt class="docutils literal"><span class="pre">alg_id</span></tt>, specifies which PRF to use. Currently defined values are</p> <table border="1" class="docutils"> <colgroup> <col width="33%" /> <col width="67%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">Value</th> <th class="head">PRF algorithm</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td>0</td> <td>HMAC(SHA-1)</td> </tr> <tr class="row-odd"><td>1</td> <td>HMAC(SHA-256)</td> </tr> <tr class="row-even"><td>2</td> <td>CMAC(Blowfish)</td> </tr> </tbody> </table> </dd></dl> <dl class="function"> <dt id="check_passhash9__ssCR.ssCR"> bool <tt class="descname">check_passhash9</tt><big>(</big>const std::string& <em>password</em>, const std::string& <em>hash</em><big>)</big><a class="headerlink" href="#check_passhash9__ssCR.ssCR" title="Permalink to this definition">¶</a></dt> <dd><p>Functions much like <tt class="docutils literal"><span class="pre">check_bcrypt</span></tt></p> </dd></dl> </div> </div> </div> </div> </div> </div> <div class="sidebar"> <h3>Table Of Contents</h3> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="index.html">Welcome</a></li> <li class="toctree-l1"><a class="reference internal" href="reading.html">Recommended Reading</a></li> <li class="toctree-l1"><a class="reference internal" href="building.html">Building The Library</a></li> <li class="toctree-l1"><a class="reference internal" href="firststep.html">Getting Started</a></li> <li class="toctree-l1"><a class="reference internal" href="filters.html">Information Flow: Pipes and Filters</a></li> <li class="toctree-l1"><a class="reference internal" href="pubkey.html">Public Key Cryptography</a></li> <li class="toctree-l1"><a class="reference internal" href="x509.html">Certificate Handling</a></li> <li class="toctree-l1"><a class="reference internal" href="ssl.html">SSL and TLS</a></li> <li class="toctree-l1"><a class="reference internal" href="bigint.html">BigInt</a></li> <li class="toctree-l1"><a class="reference internal" href="lowlevel.html">The Low-Level Interface</a></li> <li class="toctree-l1"><a class="reference internal" href="secmem.html">Secure Memory Containers</a></li> <li class="toctree-l1"><a class="reference internal" href="kdf.html">Key Derivation Functions</a></li> <li class="toctree-l1"><a class="reference internal" href="pbkdf.html">PBKDF Algorithms</a></li> <li class="toctree-l1 current"><a class="current reference internal" href="">Password Hashing</a><ul> <li class="toctree-l2"><a class="reference internal" href="#bcrypt-password-hashing">Bcrypt Password Hashing</a></li> <li class="toctree-l2"><a class="reference internal" href="#passhash9">Passhash9</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="rng.html">Random Number Generators</a></li> <li class="toctree-l1"><a class="reference internal" href="fpe.html">Format Preserving Encryption</a></li> <li class="toctree-l1"><a class="reference internal" href="python.html">Python Binding</a></li> </ul> <h3 style="margin-top: 1.5em;">Search</h3> <form class="search" action="search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <div class="clearer"></div> </div> </div> <div class="footer-wrapper"> <div class="footer"> <div class="left"> <a href="pbkdf.html" title="PBKDF Algorithms" accesskey="P">previous</a> | <a href="rng.html" title="Random Number Generators" accesskey="N">next</a> | <a href="genindex.html" title="General Index" accesskey="I">index</a> <br/> <a href="_sources/passhash.txt" rel="nofollow">Show Source</a> </div> <div class="right"> <div class="footer"> © Copyright 2000-2011, Jack Lloyd. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.3. </div> </div> <div class="clearer"></div> </div> </div> </body> </html>