{
  "name": "elithrar/simple-scrypt",
  "version": "0.1.4",
  "libraries": {
    "xv": "^1.1.25"
  },
  "title": "simple-scrypt",
  "branch": "",
  "style": {
    "name": "Williamsburg",
    "componentSet": {
      "nav": "nav/BasicNav",
      "header": "header/LightBannerHeader",
      "article": "article/ReaderArticle",
      "footer": "footer/BasicFooter"
    },
    "fontFamily": "Montserrat, sans-serif",
    "heading": {
      "fontWeight": 600,
      "letterSpacing": "0.1em"
    },
    "colors": {
      "text": "#666666",
      "background": "#fff",
      "primary": "#0099e0",
      "secondary": "#ab61ff",
      "highlight": "#f7b",
      "muted": "#2b2d70",
      "border": "#ccd"
    }
  },
  "content": [
    {
      "component": "nav",
      "links": [
        {
          "href": "https://github.com/elithrar/simple-scrypt",
          "text": "GitHub"
        }
      ]
    },
    {
      "component": "header",
      "heading": "simple-scrypt",
      "subhead": "A convenience library for generating, comparing and inspecting password hashes using the scrypt KDF in Go.",
      "children": [
        {
          "component": "ui/TweetButton",
          "text": "simple-scrypt: A convenience library for generating, comparing and inspecting password hashes using the scrypt KDF in Go.",
          "url": null
        },
        {
          "component": "ui/GithubButton",
          "user": "elithrar",
          "repo": "simple-scrypt"
        }
      ]
    },
    {
      "component": "article",
      "metadata": {
        "source": "github.readme"
      },
      "html": "\n<p><a href=\"https://godoc.org/github.com/elithrar/simple-scrypt\"><img src=\"https://godoc.org/github.com/elithrar/simple-scrypt?status.svg\"></a> <a href=\"https://travis-ci.org/elithrar/simple-scrypt\"><img src=\"https://travis-ci.org/elithrar/simple-scrypt.svg?branch=master\"></a></p>\n<p>simple-scrypt provides a convenience wrapper around Go&apos;s existing\n<a href=\"http://golang.org/x/crypto/scrypt\">scrypt</a> package that makes it easier to\nsecurely derive strong keys (&quot;hash user passwords&quot;). This library allows you to:</p>\n<ul>\n<li>Generate a scrypt derived key with a crytographically secure salt and sane\ndefault parameters for N, r and p.</li>\n<li>Upgrade the parameters used to generate keys as hardware improves by storing\nthem with the derived key (the scrypt spec. doesn&apos;t allow for this by\ndefault).</li>\n<li>Provide your own parameters (if you wish to).</li>\n</ul>\n<p>The API closely mirrors Go&apos;s <a href=\"https://golang.org/x/crypto/bcrypt\">bcrypt</a>\nlibrary in an effort to make it easy to migrate&#x2014;and because it&apos;s an easy to grok\nAPI.</p>\n<h2>Installation</h2>\n<p>With a <a href=\"https://golang.org/doc/code.html\">working Go toolchain</a>:</p>\n<pre>go get -u github.com/elithrar/simple-scrypt</pre><h2>Example</h2>\n<p>simple-scrypt doesn&apos;t try to re-invent the wheel or do anything &quot;special&quot;. It\nwraps the <code>scrypt.Key</code> function as thinly as possible, generates a\ncrytographically secure salt for you using Go&apos;s <code>crypto/rand</code> package, and\nreturns the derived key with the parameters prepended:</p>\n<pre><span class=\"hljs-keyword\">package</span> main\n\n<span class=\"hljs-keyword\">import</span>(\n    <span class=\"hljs-string\">&quot;fmt&quot;</span>\n    <span class=\"hljs-string\">&quot;log&quot;</span>\n\n    <span class=\"hljs-string\">&quot;github.com/elithrar/simple-scrypt&quot;</span>\n)\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">func</span> <span class=\"hljs-title\">main</span><span class=\"hljs-params\">()</span></span> {\n    <span class=\"hljs-comment\">// e.g. r.PostFormValue(&quot;password&quot;)</span>\n    passwordFromForm := <span class=\"hljs-string\">&quot;prew8fid9hick6c&quot;</span>\n\n    <span class=\"hljs-comment\">// Generates a derived key of the form &quot;N$r$p$salt$dk&quot; where N, r and p are defined as per</span>\n    <span class=\"hljs-comment\">// Colin Percival&apos;s scrypt paper: http://www.tarsnap.com/scrypt/scrypt.pdf</span>\n    <span class=\"hljs-comment\">// scrypt.Defaults (N=16384, r=8, p=1) makes it easy to provide these parameters, and</span>\n    <span class=\"hljs-comment\">// (should you wish) provide your own values via the scrypt.Params type.</span>\n    hash, err := scrypt.GenerateFromPassword([]<span class=\"hljs-keyword\">byte</span>(passwordFromForm), scrypt.DefaultParams)\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        log.Fatal(err)\n    }\n\n    <span class=\"hljs-comment\">// Print the derived key with its parameters prepended.</span>\n    fmt.Printf(<span class=\"hljs-string\">&quot;%s\\n&quot;</span>, hash)\n\n    <span class=\"hljs-comment\">// Uses the parameters from the existing derived key. Return an error if they don&apos;t match.</span>\n    err := scrypt.CompareHashAndPassword(hash, []<span class=\"hljs-keyword\">byte</span>(passwordFromForm))\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        log.Fatal(err)\n    }\n}</pre><h2>Upgrading Parameters</h2>\n<p>Upgrading derived keys from a set of parameters to a &quot;stronger&quot; set of parameters\nas hardware improves, or as you scale (and move your auth process to separate\nhardware), can be pretty useful. Here&apos;s how to do it with simple-scrypt:</p>\n<pre><span class=\"hljs-function\"><span class=\"hljs-keyword\">func</span> <span class=\"hljs-title\">main</span><span class=\"hljs-params\">()</span></span> {\n    <span class=\"hljs-comment\">// SCENE: We&apos;ve successfully authenticated a user, compared their submitted</span>\n    <span class=\"hljs-comment\">// (cleartext) password against the derived key stored in our database, and</span>\n    <span class=\"hljs-comment\">// now want to upgrade the parameters (more rounds, more parallelism) to</span>\n    <span class=\"hljs-comment\">// reflect some shiny new hardware we just purchased. As the user is logging</span>\n    <span class=\"hljs-comment\">// in, we can retrieve the parameters used to generate their key, and if</span>\n    <span class=\"hljs-comment\">// they don&apos;t match our &quot;new&quot; parameters, we can re-generate the key while</span>\n    <span class=\"hljs-comment\">// we still have the cleartext password in memory</span>\n    <span class=\"hljs-comment\">// (e.g. before the HTTP request ends).</span>\n    current, err := scrypt.Cost(hash)\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        log.Fatal(err)\n    }\n\n    <span class=\"hljs-comment\">// Now to check them against our own Params struct (e.g. using reflect.DeepEquals)</span>\n    <span class=\"hljs-comment\">// and determine whether we want to generate a new key with our &quot;upgraded&quot; parameters.</span>\n    slower := scrypt.Params{\n        N: <span class=\"hljs-number\">32768</span>,\n        R: <span class=\"hljs-number\">8</span>,\n        P: <span class=\"hljs-number\">2</span>,\n        SaltLen: <span class=\"hljs-number\">16</span>,\n        DKLen: <span class=\"hljs-number\">32</span>,\n    }\n\n    <span class=\"hljs-keyword\">if</span> !reflect.DeepEqual(current, slower) {\n        <span class=\"hljs-comment\">// Re-generate the key with the slower parameters</span>\n        <span class=\"hljs-comment\">// here using scrypt.GenerateFromPassword</span>\n    }\n}</pre><h2>Automatically Determining Parameters</h2>\n<p>Thanks to the work by <a href=\"https://github.com/tgulacsi\">tgulacsi</a>, you can have simple-scrypt\nautomatically determine the optimal parameters for you (time vs. memory). You should run this once\non program startup, as calibrating parameters can be an expensive operation.</p>\n<pre><span class=\"hljs-keyword\">var</span> params scrypt.Params\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">func</span> <span class=\"hljs-title\">main</span><span class=\"hljs-params\">()</span></span> {\n    <span class=\"hljs-keyword\">var</span> err error\n    <span class=\"hljs-comment\">// 500ms, 64MB of RAM per hash.</span>\n    params, err = scrypt.Calibrate(<span class=\"hljs-number\">500</span>*time.Millisecond, <span class=\"hljs-number\">64</span>, Params{})\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">nil</span>, err\n    }\n\n    ...\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">func</span> <span class=\"hljs-title\">RegisterUserHandler</span><span class=\"hljs-params\">(w http.ResponseWriter, r *http.Request)</span></span> {\n    err := r.ParseForm()\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        http.Error(w, err.Error(), http.StatusBadRequest)\n        <span class=\"hljs-keyword\">return</span>\n    }\n\n    <span class=\"hljs-comment\">// Make sure you validate: not empty, not too long, etc.</span>\n    email := r.PostFormValue(<span class=\"hljs-string\">&quot;email&quot;</span>)\n    pass := r.PostFormValue(<span class=\"hljs-string\">&quot;password&quot;</span>)\n\n    <span class=\"hljs-comment\">// Use our calibrated parameters</span>\n    hash, err := scrypt.GenerateFromPassword([]<span class=\"hljs-keyword\">byte</span>(pass), params)\n    <span class=\"hljs-keyword\">if</span> err != <span class=\"hljs-literal\">nil</span> {\n        http.Error(w, err.Error(), http.StatusBadRequest)\n        <span class=\"hljs-keyword\">return</span>\n    }\n\n    <span class=\"hljs-comment\">// Save to DB, etc.</span>\n}</pre><p>Be aware that increasing these, whilst making it harder to brute-force the resulting hash, also\nincreases the risk of a denial-of-service attack against your server. A surge in authenticate\nattempts (even if legitimate!) could consume all available resources.</p>\n<h2>License</h2>\n<p>MIT Licensed. See LICENSE file for details.</p>\n"
    },
    {
      "component": "footer",
      "links": [
        {
          "href": "https://github.com/elithrar/simple-scrypt",
          "text": "GitHub"
        },
        {
          "href": "https://github.com/elithrar",
          "text": "elithrar"
        }
      ]
    }
  ]
}