{"componentChunkName":"component---gatsby-theme-teklog-src-templates-post-tsx","path":"/php-7-2-and-argon2-password-hashing","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://blog.tekmi.nl","author":{"name":"Teklog","avatar":"/img/tekmi-icon.svg"}}},"blogPost":{"frontmatter":{"title":"PHP 7.2 and Argon2 Password Hashing","slug":"php-7-2-and-argon2-password-hashing","series":null,"date":"2018-07-19","datePretty":"19 July, 2018","coverImage":{"childImageSharp":{"fixed":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUCAwT/xAAVAQEBAAAAAAAAAAAAAAAAAAABAP/aAAwDAQACEAMQAAAB30qYI0FYX//EABsQAAICAwEAAAAAAAAAAAAAAAABAiEQERIi/9oACAEBAAEFAvSc9nM2WXj/xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPwGH/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oACAECAQE/AdK//8QAGBAAAwEBAAAAAAAAAAAAAAAAAAEyEDH/2gAIAQEABj8C2mUzrP/EABoQAAMBAAMAAAAAAAAAAAAAAAABEVFBkeH/2gAIAQEAAT8h4po43iEpUnCzF3kNX7n/2gAMAwEAAgADAAAAEBgf/8QAFhEBAQEAAAAAAAAAAAAAAAAAABFR/9oACAEDAQE/EK1H/8QAFhEBAQEAAAAAAAAAAAAAAAAAABFR/9oACAECAQE/EIxb/8QAHBABAQACAgMAAAAAAAAAAAAAAREAIVGRMUHR/9oACAEBAAE/EBsQPZjaz2JjYPymPnn6rhhSqc7fuNNd3P/Z","width":1000,"height":750,"src":"/static/07f6341383c50dc48b3a5a77029526b0/a7715/woodenRing.jpg","srcSet":"/static/07f6341383c50dc48b3a5a77029526b0/a7715/woodenRing.jpg 1x"}}},"author":null,"authorAvatar":null},"timeToRead":8,"excerpt":"Introduction PHP 7.2 version appeared for the first time on 30th of November 2017, Time goes fast and more than a half year later, on 21st of June…","html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>PHP 7.2 version appeared for the first time on <a href=\"http://php.net/archive/2017.php#id2017-11-30-1\">30th of November 2017</a>, Time goes fast and more than a half year later, on <a href=\"http://php.net/downloads.php#v7.2.7\">21st of June 2018</a>, PHP announced <em>7.2.7</em> patch release. Among all the new features introduced in PHP 7.2, there is one, namely <a href=\"https://wiki.php.net/rfc/argon2_password_hash\">Argon2 Password Hashing</a>, which will be the topic of our today's post. Let's explore this great addition together and verify whether Argon2 is a good contender to Bcrypt or not.</p>\n<p>As always, all the other features of PHP 7.2 can be found under <a href=\"https://wiki.php.net/rfc#php_72\">Request For Changes</a> wiki page.</p>\n<h2 id=\"assumptions\" style=\"position:relative;\"><a href=\"#assumptions\" aria-label=\"assumptions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Assumptions</h2>\n<ul>\n<li><a href=\"https://docs.docker.com/engine/installation/#supported-platforms\">Docker is installed</a>.</li>\n</ul>\n<h2 id=\"try-it-yourself\" style=\"position:relative;\"><a href=\"#try-it-yourself\" aria-label=\"try it yourself permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Try it yourself</h2>\n<p>Clone <strong>blogging-phplatest</strong> repository</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">git</span> clone https://github.com/tekmi/blogging-phplatest\n<span class=\"token builtin class-name\">cd</span> blogging-phplatest</code></pre></div>\n<p>Run docker container, based on the <a href=\"https://hub.docker.com/_/php/\">php 7.2.7-cli-stretch</a> image.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">docker run -it --rm <span class=\"token punctuation\">\\</span>\n-v <span class=\"token string\">\"<span class=\"token environment constant\">$PWD</span>\"</span>:/usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\n-w /usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\nphp:7.2.7-cli-stretch <span class=\"token punctuation\">\\</span>\nphp php-7.2/argon2_password_hash/index.php</code></pre></div>\n<h2 id=\"explanation\" style=\"position:relative;\"><a href=\"#explanation\" aria-label=\"explanation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Explanation</h2>\n<p><a href=\"https://password-hashing.net/argon2-specs.pdf\">Argon2</a> comes in two flavors, <em>Argon2d</em> and <em>Argon2i</em>. The former one is recommended primarily for cryptocurrencies and backend servers, while the latter for password hashing and password-based derivation. Due to this difference, RFC implementing Argon2 in PHP doesn't provide Argon2d flavor - therefore no unnecessary <code class=\"language-text\">PASSWORD_ARGON2</code> constant.</p>\n<p>You can verify it by exploring Argon2 related named constants that come with PHP 7.2 version.</p>\n<ul>\n<li><code class=\"language-text\">PASSWORD_ARGON2I</code> which shall be used to create new password hashes using Argon2 algorithm and its value is integer <em>2</em>. If you compare it to <code class=\"language-text\">PASSWORD_DEFAULT</code>(which is integer <em>1</em>), you may infer it's not the default hashing algorithm. Like it or not, Bcrypt is still the default one. To prove it, check out <code class=\"language-text\">PASSWORD_BCRYPT</code> named constant, which is integer <em>1</em>. There were some talks to make Argon2 default algorithm in PHP 7.4, but apparently this won't happen anymore.</li>\n<li>Three named constants that define some sane defaults for Argon2, namely <code class=\"language-text\">PASSWORD_ARGON2_DEFAULT_MEMORY_COST</code>, <code class=\"language-text\">PASSWORD_ARGON2_DEFAULT_TIME_COST</code> and <code class=\"language-text\">PASSWORD_ARGON2_DEFAULT_THREADS</code>. Reading the RFC, looks like the sane defaults have been revised and now are <em>1024</em> bytes, <em>2</em> and <em>2</em> respectively.</li>\n</ul>\n<p>If somehow you cannot use those variables, make sure you had compiled your PHP <em>--with-password-argon2</em> , since this ensures <em>libargon2</em> have been included. Docker image being used here has it compiled - feel free to double check it by running:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">docker run -it --rm <span class=\"token punctuation\">\\</span>\n-v <span class=\"token string\">\"<span class=\"token environment constant\">$PWD</span>\"</span>:/usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\n-w /usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\nphp:7.2.7-cli-stretch <span class=\"token punctuation\">\\</span>\n-r <span class=\"token string\">\"phpinfo();\"</span> <span class=\"token operator\">|</span> <span class=\"token function\">grep</span> argon2</code></pre></div>\n<p>What interested me was why Argon2i Algorithm gained so much traction and if Bcrypt is still the valid option.</p>\n<p>Reading <a href=\"https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Leverage_an_adaptive_one-way_function\">OWASP</a> cheatsheets about password hashing, looks like there are three other viable contenders, namely <em>PBKDF2</em>, <em>scrypt</em> and <em>bcrypt</em>. While OWASP prefers Argon2, looks like <a href=\"https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software#secure-php-passwords\">Paragonie</a> is fine with default Bcrypt. Any of the aforementioned algorithms are good and still considered secure, but when it comes to my preference:</p>\n<ul>\n<li>I like the fact that Argon2 won the <a href=\"https://password-hashing.net/\">Password Hashing Competition</a>  in July 2015, beating other contenders, including <a href=\"https://www.uni-weimar.de/de/medien/professuren/medieninformatik/mediensicherheit/research/catena/\">Catena</a>, <a href=\"https://en.wikipedia.org/wiki/Lyra2\">Lyra2</a>, Makwa and <a href=\"http://www.openwall.com/presentations/PHDays2014-Yescrypt/\">yescrypt</a>.</li>\n<li>Bcrypt was invented in 1999 and PHP made it default password hashing algorithm since version 5.5.0 (around June 2013), so time to switch to something newer.</li>\n<li>In general, I would not rely on <code class=\"language-text\">PASSWORD_DEFAULT</code> constant in PHP and always explicitly state which hashing algorithm to use - less problems with PHP updates.</li>\n</ul>\n<p>Having said all of this, let's see how to use Argon2 new algorithm to our advantage by exploring the <a href=\"http://php.net/manual/en/function.password-hash.php\">password_hash</a> function.</p>\n<p>In the basic form, Argon2 password hashing works with following defaults (<em>memory cost: 1024, time cost: 2, threads: 2</em>) and can be invoked as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$hashed</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token double-quoted-string string\">\"tekmi\"</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>If you don't like the defaults, Argon2 accepts additional options, that can be passed as third parameter to password_hash function. Scan <a href=\"http://nl1.php.net/manual/en/password.constants.php\">PHP Predefined Password Hashing Constant</a> page in order to learn more. In the example below you can see all of them adjusted at once.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$hashed</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token double-quoted-string string\">\"tekmi\"</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>\n <span class=\"token single-quoted-string string\">'memory_cost'</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">2</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span> <span class=\"token number\">12</span><span class=\"token punctuation\">,</span>\n <span class=\"token single-quoted-string string\">'time_cost'</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">10</span><span class=\"token punctuation\">,</span>\n <span class=\"token single-quoted-string string\">'threads'</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">20</span>\n<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Be warned that tweaking up those values too much, can drastically increase the execution time of your script. </p>\n<hr>\n<p>To give you an example, with params (<em>memory cost: 1048576, time cost: 1000, threads: 50</em>), this call took 440 seconds before it was finished! Moreover Memory usage was 1.014Gib, CPU was at 391.38% and the number of PIDS oscillated around 50.</p>\n<hr>\n<p>If you specify too crazy values, you can additionally come across one of the following errors.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token operator\">-</span> Warning<span class=\"token punctuation\">:</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span> Memory cost is outside of allowed memory range in <span class=\"token operator\">/</span>usr<span class=\"token operator\">/</span>src<span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>argon2_password_hash<span class=\"token operator\">/</span>index<span class=\"token punctuation\">.</span>php on line <span class=\"token number\">20</span>\n<span class=\"token operator\">-</span> Warning<span class=\"token punctuation\">:</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span> Time cost is outside of allowed time range in <span class=\"token operator\">/</span>usr<span class=\"token operator\">/</span>src<span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>argon2_password_hash<span class=\"token operator\">/</span>index<span class=\"token punctuation\">.</span>php on line <span class=\"token number\">20</span>\n<span class=\"token operator\">-</span> Warning<span class=\"token punctuation\">:</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span> Invalid number of threads in <span class=\"token operator\">/</span>usr<span class=\"token operator\">/</span>src<span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>argon2_password_hash<span class=\"token operator\">/</span>index<span class=\"token punctuation\">.</span>php on line <span class=\"token number\">20</span>\n<span class=\"token operator\">-</span> Warning<span class=\"token punctuation\">:</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span> Memory cost is too small in <span class=\"token operator\">/</span>usr<span class=\"token operator\">/</span>src<span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>php<span class=\"token operator\">-</span><span class=\"token number\">7.2</span><span class=\"token operator\">/</span>argon2_password_hash<span class=\"token operator\">/</span>index<span class=\"token punctuation\">.</span>php on line <span class=\"token number\">20</span></code></pre></div>\n<p>You may tinker with this by uncommenting a few lines in <a href=\"https://github.com/tekmi/blogging-phplatest/blob/master/php-7.2/argon2_password_hash/index.php#L37\">index.php</a> script and re-run <a href=\"https://docs.docker.com/config/containers/resource_constraints/\">container</a> with memory limited to 1 GiB, as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">docker run -it --rm <span class=\"token punctuation\">\\</span>\n-v <span class=\"token string\">\"<span class=\"token environment constant\">$PWD</span>\"</span>:/usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\n-w /usr/src/php-7.2 <span class=\"token punctuation\">\\</span>\n--memory<span class=\"token operator\">=</span><span class=\"token string\">'1g'</span> --cpus<span class=\"token operator\">=</span><span class=\"token string\">'.5'</span> <span class=\"token punctuation\">\\</span>\nphp:7.2.7-cli-stretch <span class=\"token punctuation\">\\</span>\nphp php-7.2/argon2_password_hash/index.php</code></pre></div>\n<p>I couldn't find much information about those limits, so by trial and error, I figured out some of them, e.g: threads limit 30000000, time limit 900000000000, and surprisingly memory limit 4294967296, even if my container was limited to only 1 GiB memory.</p>\n<p>By now we successfully hashed our password 'tekmi', which shall resemble something like <code class=\"language-text\">$argon2i$v=19$m=1024,t=2,p=2$YU9GN280WU1icm0zVC9sRg$oCiQ7N4liAGYrkFxW9gTDY/gBKXIHizVEKcZcz72tqw</code> or <code class=\"language-text\">$argon2i$v=19$m=1024,t=2,p=2$VTBsd0dLeVQydm9PdWlmQQ$t8AFo0XU1zGR0hLgzJFxUQkZ3YQL49pqwbAcdhRYn84</code>. As you see, the same password with the same Argon2 defaults, will always result in different string.</p>\n<p>Additionally, if you study <a href=\"http://php.net/manual/en/ref.password.php\">PHP Password Hashing functions</a> page, you can see three other functions. Let's start with <a href=\"http://php.net/manual/en/function.password-get-info.php\">password_get_info</a>, which will give you details of the hashed password, as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$hashed</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token double-quoted-string string\">\"tekmi\"</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token variable\">$info</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_get_info</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$hashed</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">var_dump</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$info</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// result</span>\n<span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"algo\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n  <span class=\"token function\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"algoName\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n  <span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token number\">7</span><span class=\"token punctuation\">)</span> <span class=\"token double-quoted-string string\">\"argon2i\"</span>\n  <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"options\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n  <span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"memory_cost\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n    <span class=\"token function\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">1024</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"time_cost\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n    <span class=\"token function\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"threads\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n    <span class=\"token function\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If you call it with hash that doesn't make sense, you get unknown algorithm name and algorithm value is integer <em>0</em>, as shown below.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$info</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_get_info</span><span class=\"token punctuation\">(</span><span class=\"token single-quoted-string string\">'SomeRandomString'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> \n<span class=\"token function\">var_dump</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$info</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// result</span>\n<span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"algo\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n <span class=\"token function\">int</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"algoName\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n <span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token number\">7</span><span class=\"token punctuation\">)</span> <span class=\"token double-quoted-string string\">\"unknown\"</span>\n <span class=\"token punctuation\">[</span><span class=\"token double-quoted-string string\">\"options\"</span><span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token operator\">></span>\n <span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>After this part is clear, let's explore <a href=\"http://php.net/manual/en/function.password-needs-rehash.php\">password_needs_rehash</a> function, which can detect if given hash shall be rehashed. This can happen if you hashed your password with default Argon2 options, saved this hash in your database and later on decided to adjust your code to introduce different Argon2 options (e.g:  time_cost, memory_cost or threads). Below snippet presents such situation.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$hashed</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token double-quoted-string string\">\"tekmi\"</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> \n<span class=\"token variable\">$needsRehashing1</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_needs_rehash</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$hashed</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token variable\">$needsRehashing2</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_needs_rehash</span><span class=\"token punctuation\">(</span><span class=\"token variable\">$hashed</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token single-quoted-string string\">'time_cost'</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">var_dump</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token variable\">$needsRehashing1</span><span class=\"token punctuation\">,</span> <span class=\"token variable\">$needsRehashing2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// result</span>\n<span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token function\">bool</span><span class=\"token punctuation\">(</span><span class=\"token boolean constant\">false</span><span class=\"token punctuation\">)</span>\n <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token function\">bool</span><span class=\"token punctuation\">(</span><span class=\"token boolean constant\">true</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And finally onto the last function, <a href=\"http://php.net/manual/en/function.password-verify.php\">password_verify</a>, which can verify if given hash matches given password. Let's see it in action in the snippet below.</p>\n<div class=\"gatsby-highlight\" data-language=\"php\"><pre class=\"language-php\"><code class=\"language-php\"><span class=\"token variable\">$hashed</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_hash</span><span class=\"token punctuation\">(</span><span class=\"token double-quoted-string string\">\"tekmi\"</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_ARGON2I</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token variable\">$verified1</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_verify</span><span class=\"token punctuation\">(</span><span class=\"token single-quoted-string string\">'tekmi'</span><span class=\"token punctuation\">,</span> <span class=\"token variable\">$hashed</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token variable\">$verified2</span> <span class=\"token operator\">=</span> <span class=\"token function\">password_verify</span><span class=\"token punctuation\">(</span><span class=\"token single-quoted-string string\">'otherPassword'</span><span class=\"token punctuation\">,</span> <span class=\"token variable\">$hashed</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">var_dump</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token variable\">$verified1</span><span class=\"token punctuation\">,</span> <span class=\"token variable\">$verified2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// result</span>\n<span class=\"token keyword\">array</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token function\">bool</span><span class=\"token punctuation\">(</span><span class=\"token boolean constant\">true</span><span class=\"token punctuation\">)</span>\n <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token function\">bool</span><span class=\"token punctuation\">(</span><span class=\"token boolean constant\">false</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"how-did-we-do-it-until-now\" style=\"position:relative;\"><a href=\"#how-did-we-do-it-until-now\" aria-label=\"how did we do it until now permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How did we do it until now</h2>\n<p>PHP from version 5.5.0 decided to integrate Bcrypt algorithm, making it the default password hashing algorithm. So this was and still is the viable and secure option, if one doesn't like or cannot take advantage of Argon2.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>It's great to see PHP evolving and incorporating new things into the codebase. It ensures me that the language is vivid and manages to keep up with the latest trends - therefore I wanted to thank all the PHP contributors for their heavy and dedicated work.</p>\n<p>If you are about to start a new project or you are still hashing passwords with MD5 or SHA, consider trying out the new brand Argon2 algorithms. If you have old project though, which works perfectly with Bcrypt, don't rush and update all your codebase - the situation you are in is totally fine and shall be fine for years to come - in the end Bcrypt has been battle tested and has established high security standards.</p>\n<p>In the upcoming post, I would explore another great addition to PHP 7.2, namely Libsodium, so see you there.</p>"}},"pageContext":{"postId":"7e53e071-c5cb-5951-a8ef-03f7a073aef7","slug":"php-7-2-and-argon2-password-hashing"}}}