<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cryptography on Guillaume Delré</title><link>https://guillaumedelre.github.io/tags/cryptography/</link><description>Recent content in Cryptography on Guillaume Delré</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 14 Jan 2018 00:00:00 +0000</lastBuildDate><atom:link href="https://guillaumedelre.github.io/tags/cryptography/index.xml" rel="self" type="application/rss+xml"/><item><title>PHP 7.2: goodbye mcrypt, hello sodium</title><link>https://guillaumedelre.github.io/2018/01/14/php-7.2-goodbye-mcrypt-hello-sodium/</link><pubDate>Sun, 14 Jan 2018 00:00:00 +0000</pubDate><guid>https://guillaumedelre.github.io/2018/01/14/php-7.2-goodbye-mcrypt-hello-sodium/</guid><description>Part 3 of 11 in &amp;quot;PHP Releases&amp;quot;: PHP 7.2 removes the unmaintained mcrypt extension and bundles libsodium — finally modernizing PHP&amp;#39;s cryptography story.</description><category>php-releases</category><content:encoded><![CDATA[<p>PHP 7.2 released November 30th. The headline isn&rsquo;t a language feature, it&rsquo;s a removal. <code>mcrypt</code> is gone.</p>
<p>This is good news, even if it doesn&rsquo;t feel that way when you&rsquo;re the one migrating.</p>
<h2 id="the-mcrypt-problem">The mcrypt problem</h2>
<p><code>mcrypt</code> has been unmaintained since 2007. More than a decade of stagnation in a cryptography library. It was deprecated in 7.1, and 7.2 removes it entirely. The replacement is <code>sodium</code>, now bundled as a core extension.</p>
<p>Sodium is the PHP binding for <a href="https://libsodium.org" target="_blank" rel="noopener noreferrer">libsodium</a>, a modern cryptographic library built around safe defaults. Where mcrypt required you to pick the right cipher, mode, and padding (and get it wrong silently), sodium&rsquo;s API makes dangerous choices structurally hard. <code>sodium_crypto_secretbox()</code> for symmetric encryption, <code>sodium_crypto_box()</code> for asymmetric, <code>sodium_crypto_sign()</code> for signatures. The names tell you what you&rsquo;re doing.</p>
<p>If you have mcrypt code in production, the migration is unavoidable. Worth doing carefully too: cryptography code that &ldquo;still works&rdquo; can be silently broken in ways you won&rsquo;t notice until it&rsquo;s too late.</p>
<h2 id="the-object-type-hint">The object type hint</h2>
<p>7.2 adds <code>object</code> as a parameter and return type:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">serialize</span>(<span style="color:#a6e22e">object</span> $data)<span style="color:#f92672">:</span> <span style="color:#a6e22e">string</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// accepts any object
</span></span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>It&rsquo;s broad — any object satisfies it — but it&rsquo;s better than no type at all when you genuinely don&rsquo;t care about the specific class. Complements the existing <code>array</code>, <code>callable</code>, and class-specific hints.</p>
<h2 id="argon2-in-password_hash">Argon2 in password_hash</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$hash <span style="color:#f92672">=</span> <span style="color:#a6e22e">password_hash</span>($password, <span style="color:#a6e22e">PASSWORD_ARGON2I</span>);
</span></span></code></pre></div><p><code>PASSWORD_BCRYPT</code> was the default and still reasonable, but Argon2 won the Password Hashing Competition for a reason: it&rsquo;s memory-hard, which makes GPU-based cracking significantly more expensive. Worth switching for new apps.</p>
<p>7.2 is more of a security release than a language one. Remove mcrypt, add sodium, and you&rsquo;ve moved the platform to a place where you can actually trust it with sensitive data. The language features are incremental. The infrastructure shift is not.</p>
<h2 id="parameter-types-you-can-now-drop-on-purpose">Parameter types you can now drop on purpose</h2>
<p>7.2 formalizes something that was previously just a smell: when you implement an interface or override a method, you can now omit the parameter type entirely. This is valid contravariance under the Liskov substitution principle.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Serializable</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">serialize</span>(<span style="color:#66d9ef">array</span> $data)<span style="color:#f92672">:</span> <span style="color:#a6e22e">string</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">JsonSerializer</span> <span style="color:#66d9ef">implements</span> <span style="color:#a6e22e">Serializable</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">serialize</span>($data)<span style="color:#f92672">:</span> <span style="color:#a6e22e">string</span> { <span style="color:#75715e">// no type — accepts more, still valid
</span></span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">json_encode</span>($data);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>It reads oddly at first. But it&rsquo;s logically sound: a method that accepts anything is strictly more permissive than one that only accepts arrays. The type system agrees, even if your code reviewer raises an eyebrow.</p>
<h2 id="abstract-methods-that-evolve">Abstract methods that evolve</h2>
<p>When an abstract class extends another abstract class, it can now override the abstract method with a different signature. The constraint is directional: parameters can be widened (contravariant), return types can be narrowed (covariant).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">BaseProcessor</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">process</span>(<span style="color:#a6e22e">string</span> $input);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TypedProcessor</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">BaseProcessor</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">process</span>($input)<span style="color:#f92672">:</span> <span style="color:#a6e22e">int</span>; <span style="color:#75715e">// parameter widened, return type added
</span></span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>This was rejected before 7.2. It unlocks intermediate abstractions without forcing every leaf class to repeat the same signature.</p>
<h2 id="trailing-commas-in-grouped-use-statements">Trailing commas in grouped use statements</h2>
<p>Small, but I notice its absence when it&rsquo;s missing. Grouped namespace imports can now have a trailing comma on the last item:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Services\</span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">UserService</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">OrderService</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">NotificationService</span>, <span style="color:#75715e">// comma here — finally
</span></span></span><span style="display:flex;"><span>};
</span></span></code></pre></div><p>This means you can reorder or add lines without touching the previous last entry. Git diffs get cleaner, merge conflicts get rarer.</p>
<h2 id="count-grew-a-conscience"><code>count()</code> grew a conscience</h2>
<p>Before 7.2, <code>count(null)</code> returned 0. Silently. No warning. That&rsquo;s exactly the kind of thing that buries a bug for months. Now it emits <code>E_WARNING</code> when you pass something that isn&rsquo;t an array or a <code>Countable</code> object.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">count</span>(<span style="color:#66d9ef">null</span>);  <span style="color:#75715e">// Warning: count(): Parameter must be an array or an object that implements Countable
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">count</span>(<span style="color:#ae81ff">42</span>);    <span style="color:#75715e">// same
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">count</span>(<span style="color:#e6db74">&#34;hi&#34;</span>);  <span style="color:#75715e">// same
</span></span></span></code></pre></div><p>The behavior didn&rsquo;t change for valid inputs. Only the silence was broken. That&rsquo;s the correct direction.</p>
<h2 id="spl_object_id--the-thing-you-were-emulating-with-splobjectstorage"><code>spl_object_id()</code> — the thing you were emulating with SplObjectStorage</h2>
<p>If you&rsquo;ve ever built a map keyed on object identity, you&rsquo;ve written something like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$storage <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">SplObjectStorage</span>();
</span></span><span style="display:flex;"><span>$storage[$obj] <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span></code></pre></div><p>7.2 adds <code>spl_object_id()</code>, which returns a unique integer for the lifetime of an object. It&rsquo;s the same internal handle <code>SplObjectStorage</code> uses, made directly accessible:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$id <span style="color:#f92672">=</span> <span style="color:#a6e22e">spl_object_id</span>($obj); <span style="color:#75715e">// e.g. 42
</span></span></span><span style="display:flex;"><span>$map[$id] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;something&#39;</span>;
</span></span></code></pre></div><p>The integer is reused after the object is destroyed, so don&rsquo;t hold onto it past the object&rsquo;s lifetime. Within a well-scoped context though, it&rsquo;s a cheap identity key.</p>
<h2 id="pdo-national-character-strings">PDO: national character strings</h2>
<p>When working with databases that distinguish between regular and national character string types (Oracle, SQL Server), 7.2 adds the flags you needed:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$stmt <span style="color:#f92672">=</span> $pdo<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">prepare</span>(<span style="color:#e6db74">&#34;SELECT * FROM users WHERE name = ?&#34;</span>);
</span></span><span style="display:flex;"><span>$stmt<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">bindValue</span>(<span style="color:#ae81ff">1</span>, <span style="color:#e6db74">&#39;Ångström&#39;</span>, <span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">PARAM_STR</span> <span style="color:#f92672">|</span> <span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">PARAM_STR_NATL</span>);
</span></span></code></pre></div><p>Or set a connection-level default:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$pdo<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setAttribute</span>(<span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">ATTR_DEFAULT_STR_PARAM</span>, <span style="color:#a6e22e">PDO</span><span style="color:#f92672">::</span><span style="color:#a6e22e">PARAM_STR_NATL</span>);
</span></span></code></pre></div><p><code>PDO::PARAM_STR_NATL</code> signals that the string is a national character type (NCHAR/NVARCHAR). Obscure, yes. Essential if you&rsquo;ve ever watched your Unicode data come out mangled because the driver had no idea about the difference.</p>
<h2 id="gd-got-bmp-support-and-clipping-rectangles">GD got BMP support and clipping rectangles</h2>
<p>Two things worth knowing. First, BMP files are now first-class citizens in the GD extension:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$image <span style="color:#f92672">=</span> <span style="color:#a6e22e">imagecreatefrombmp</span>(<span style="color:#e6db74">&#39;photo.bmp&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">imagebmp</span>($image, <span style="color:#e6db74">&#39;output.bmp&#39;</span>);
</span></span></code></pre></div><p>Second, you can now define a clipping rectangle so that drawing operations only affect a portion of the image:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">imagesetclip</span>($image, <span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">200</span>, <span style="color:#ae81ff">150</span>); <span style="color:#75715e">// x1, y1, x2, y2
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// everything drawn outside this rectangle is silently ignored
</span></span></span></code></pre></div><p>Neither feature reshapes how most apps work, but both replace &ldquo;install an extra library&rdquo; with &ldquo;it&rsquo;s just in core now.&rdquo;</p>
<h2 id="mb_chr-and-mb_ord--unicodes-chr-and-ord"><code>mb_chr()</code> and <code>mb_ord()</code> — Unicode&rsquo;s <code>chr()</code> and <code>ord()</code></h2>
<p>PHP has had <code>chr()</code> and <code>ord()</code> forever. They work on bytes. For Unicode code points, you were on your own. 7.2 adds the multibyte equivalents:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$char <span style="color:#f92672">=</span> <span style="color:#a6e22e">mb_chr</span>(<span style="color:#ae81ff">0x1F600</span>); <span style="color:#75715e">// returns the 😀 emoji
</span></span></span><span style="display:flex;"><span>$code <span style="color:#f92672">=</span> <span style="color:#a6e22e">mb_ord</span>(<span style="color:#e6db74">&#39;é&#39;</span>);     <span style="color:#75715e">// returns 233
</span></span></span></code></pre></div><p>And <code>mb_scrub()</code>, which strips invalid byte sequences from a string rather than failing silently or throwing:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$clean <span style="color:#f92672">=</span> <span style="color:#a6e22e">mb_scrub</span>($untrustedInput, <span style="color:#e6db74">&#39;UTF-8&#39;</span>);
</span></span></code></pre></div><p>Handy at any external boundary: API responses, file uploads, database reads from legacy systems.</p>
<h2 id="deprecations-worth-knowing-before-74-arrives">Deprecations worth knowing before 7.4 arrives</h2>
<p>Several things were soft-deprecated in 7.2 that will become errors in later versions. The ones most likely to bite:</p>
<p><code>__autoload()</code> is deprecated. If you&rsquo;re still registering a global autoload function instead of using <code>spl_autoload_register()</code>, fix it before it becomes a fatal.</p>
<p><code>create_function()</code> is deprecated. It&rsquo;s a wrapper around <code>eval()</code> and was always dangerous. Use a closure:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// before
</span></span></span><span style="display:flex;"><span>$fn <span style="color:#f92672">=</span> <span style="color:#a6e22e">create_function</span>(<span style="color:#e6db74">&#39;$x&#39;</span>, <span style="color:#e6db74">&#39;return $x * 2;&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// after
</span></span></span><span style="display:flex;"><span>$fn <span style="color:#f92672">=</span> <span style="color:#a6e22e">fn</span>($x) <span style="color:#f92672">=&gt;</span> $x <span style="color:#f92672">*</span> <span style="color:#ae81ff">2</span>;
</span></span></code></pre></div><p><code>each()</code> is deprecated. The loop pattern it enabled is better written as <code>foreach</code>. There&rsquo;s no loss here.</p>
<p><code>parse_str()</code> without a second argument dumps parsed values into the local symbol table — a security issue that should never have been allowed. Always pass the output variable:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">parse_str</span>($queryString, $params); <span style="color:#75715e">// correct
</span></span></span></code></pre></div><p>The <code>(unset)</code> cast is deprecated because it always returns <code>null</code>, which you can just write as <code>null</code>. Completely pointless syntax that should never have existed.</p>
]]></content:encoded></item></channel></rss>