<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Paul,</div><div><br></div><div>You are right on. bcrypt and the like are reasonable choices for low traffic websites, but can be abusive hits on CPU/L1/L2 caches and are problematic at scale. For bcrypt with work factor 10, it takes about 10 concurrent runs of bcrypt to pin a high performance CPU.</div><div><br></div><div>You have a few choices here. </div><div><br></div><div>1) Throw a lot of hardware at it. Lots. I've seen a few folks do this. It works but it's expensive.</div><div><br></div><div>2) Reduce the work factor and speed up the algorithm. Bad choice. It defeats the purpose of adaptive algorithms.</div><div><br></div><div>3) Use an HMAC, proper key storage and rotation, and cryptographic isolation of the HMAC process in a separate service or the like, so your main app server has no access to the HMAC private key.</div><div><br></div><div>Several folks critique these assertions. These ideas are backed by John Stevens extensive, nay, I dare say obsessive threat model on password storage. <a href="http://goo.gl/Spvzs">http://goo.gl/Spvzs</a></div><div><br></div><div>Until someone shows me something similar, I'm going with John's very detailed and well thought out advice.</div><div><br></div><div>Aloha,<br><div>--</div><div>Jim Manico</div><div>@Manicode</div><div>(808) 652-3805</div></div><div><br>On Jan 31, 2014, at 8:15 AM, Paul Johnston <<a href="mailto:paul.johnston@pentest.co.uk">paul.johnston@pentest.co.uk</a>> wrote:<br><br></div><blockquote type="cite"><div>
  

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  
  
    Hi,<br>
    <br>
    When storing user's passwords that you need to verify against (but
    not use as plaintext) the current state of the art is:<br>
    <br>
    1) Hash the password<br>
    2) Use a salt<br>
    3) Use a slow hash function - bcrypt, scrypt, etc.<br>
    <br>
    This provides the best possible protection against an attacker who
    has stolen the password database. It does not solve other issues
    like phishing, malware, password re-use, etc.<br>
    <br>
    BUT there is one remaining problem: the slow hash function can allow
    a denial of service attack. A single request burns a lot of CPU. In
    practice I don't think this is a major problem, given defences like
    IP throttling. But it does deter people from using a higher work
    factor, to really get the benefit of slow hashing.<br>
    <br>
    Given the improving performance of JavaScript in browsers, it may
    now make sense to do this in the browser. I'm assuming here that the
    site is using SSL, so the JavaScript is delivered securely. If
    you're not using SSL, then using a slow hash function is unlikely to
    be a priority for you. There is at least once JavaScript
    implementation of bcrypt
    (<a class="moz-txt-link-freetext" href="https://code.google.com/p/javascript-bcrypt/">https://code.google.com/p/javascript-bcrypt/</a>). But using this in a
    simple way would introduce two problems:<br>
    <br>
    1) The client needs to fetch the salt from the server. This
    introduces latency on login and, unless care is taken, can reveal
    whether a particular user account exists.<br>
    2) If hashing is done purely on the client then the benefits of
    storing hashes are lost. At attacker who has stolen the password
    hashes can simply login using the hashes.<br>
    <br>
    However, I think there are acceptable solutions to both of those
    problems:<br>
    <br>
    1) The salt can be generated as hash(server_salt + user_name) -
    where server_salt is a random number that is unique to the server,
    public, and the same for all users. The resulting hash appears to
    have the required properties of a salt.<br>
    2) The server should do a single, fast, hash operation on the hash
    it receives. As an example: the server stores SHA-256(bcrypt(salt,
    password)). The client sends bcrypt(password) then the server
    applies SHA-256 and checks the hash. This does NOT allow an attacker
    to conduct a fast offline brute force attack. They can do a fast
    brute force of SHA-256(password) because password has a limited
    amount of entropy - 2^50 or 2^60 or so. But a 128-bit
    bcrypt(password) has entropy or 2^128, so they cannot readily brute
    force it.<br>
    <br>
    Now, perhaps this has already been thought of. Perhaps people are
    actively using it (although I've never seen it). If so, apologies
    for the line noise.<br>
    <br>
    As some background on me, I was pushing JavaScript cryptography 15
    years back as a simple password defence for sites that do not use
    SSL (<a class="moz-txt-link-freetext" href="http://pajhome.org.uk/crypt/md5/">http://pajhome.org.uk/crypt/md5/</a>). This got a bit of a cult
    following, but the world has moved on since then, and really any
    site with a login should use SSL. But it seems a use for JavaScript
    password hashing has returned! I knew it would all along :-)<br>
    <br>
    Paul<br>
    <br>
    <div class="moz-signature">-- <br>
      <p><font color="#333333">Pentest - The Application Security
          Specialists</font></p>
      <p><font color="#333333">Paul Johnston - IT Security Consultant /
          Tiger SST<br>
          Office: +44 (0) 161 233 0100<br>
          Mobile: +44 (0) 7817 219 072</font></p>
      <p><font color="#000066"><strong>We're exhibiting at Infosecurity
            Europe!<br>
            Stand K97, Earl's Court London - 29th April - 1st May</strong></font><br>
        <img src="cid:part1.01000108.03090806@pentest.co.uk" alt="Infosecurity Europe 2014" height+"71"="" width="253"></p>
      <p><font color="#333333">Email policy: </font><font color="#0b6cda"><u><a class="moz-txt-link-freetext" href="http://www.pentest.co.uk/legal.shtml#emailpolicy">http://www.pentest.co.uk/legal.shtml#emailpolicy</a></u></font><br>
        Registered Number: 4217114 England & Wales<br>
        Registered Office: 26a The Downs, Altrincham, Cheshire, WA14
        2PU, UK<br>
        Accreditations: ISO 9001 (44/100/107029) / ISO 27001 (IS 558982)
        / Tiger Scheme</p>
    </div>
  

</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>The Web Security Mailing List</span><br><span></span><br><span>WebSecurity RSS Feed</span><br><span><a href="http://www.webappsec.org/rss/websecurity.rss">http://www.webappsec.org/rss/websecurity.rss</a></span><br><span></span><br><span>Join WASC on LinkedIn <a href="http://www.linkedin.com/e/gis/83336/4B20E4374DBA">http://www.linkedin.com/e/gis/83336/4B20E4374DBA</a></span><br><span></span><br><span>WASC on Twitter</span><br><span><a href="http://twitter.com/wascupdates">http://twitter.com/wascupdates</a></span><br><span></span><br><span><a href="mailto:websecurity@lists.webappsec.org">websecurity@lists.webappsec.org</a></span><br><span><a href="http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org">http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org</a></span><br></div></blockquote></body></html>