<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Scott Arciszewski</title>
    <description>The latest articles on DEV Community by Scott Arciszewski (@paragoniescott).</description>
    <link>https://dev.to/paragoniescott</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F725%2F11591518.png</url>
      <title>DEV Community: Scott Arciszewski</title>
      <link>https://dev.to/paragoniescott</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paragoniescott"/>
    <language>en</language>
    <item>
      <title>Message Encryption in JavaScript and PHP</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Sun, 20 Oct 2019 21:34:26 +0000</pubDate>
      <link>https://dev.to/paragonie/message-encryption-in-javascript-and-php-cg9</link>
      <guid>https://dev.to/paragonie/message-encryption-in-javascript-and-php-cg9</guid>
      <description>&lt;p&gt;Just for fun, let's encrypt some stuff in client-side JavaScript and have a PHP server decrypt it. Note that &lt;strong&gt;this &lt;a href="https://stackoverflow.com/a/12327375/2224584"&gt;will never replace TLS (HTTPS)&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript Encryption with Sodium-Plus
&lt;/h3&gt;

&lt;p&gt;You'll want the &lt;a href="https://github.com/paragonie/sodium-plus/releases"&gt;latest release of sodium-plus&lt;/a&gt; for this. (As of this writing, it's &lt;a href="https://github.com/paragonie/sodium-plus/releases/tag/v0.4.0"&gt;version 0.4.0&lt;/a&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script
  src="/static/js/sodium-plus.min.js"
  integrity="sha384-lv7SVE0eb0bXA3fgK6PwlhViiUwG6tBuMAhS8XX7RvBvyRcdEdJ8HKtFgs4vHTUh"
&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, you'll want to write some JavaScript code to encrypt a message and send it to a server. I'll be using jQuery for this example, but you can easily adapt it to use a &lt;code&gt;XMLHttpRequest&lt;/code&gt; object instead.&lt;/p&gt;

&lt;p&gt;Let's define two functions. One loads a &lt;code&gt;CryptographyKey&lt;/code&gt; object from a hard-coded string (n.b. you never want to actually do this, but for the sake of an easy, working example, we're using a hard-coded secret). The other actually encrypts a message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Get the example key. In the real world, you want to generate these randomly.
 */
async function getExampleKey() {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();
    return CryptographyKey.from(
        'e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0',
        'hex'
    );
    // return await sodium.crypto_secretbox_keygen();
}

/**
 * Encrypt a message under a given key.
 */
async function encryptMessage(message, key) {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();

    let nonce = await sodium.randombytes_buf(24);
    let encrypted = await sodium.crypto_secretbox(message, nonce, key);
    return nonce.toString('hex') + encrypted.toString('hex');
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, you'll want to write a function that gathers user input, encrypts it, and sends it to a server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function sendEncryptedMessage() {
    let key = await getExampleKey();
    let message = $("#user-input").val();
    let encrypted = await encryptMessage(message, key);
    $.post("/send-message", {"message": encrypted}, function (response) {
        console.log(response);
        $("#output").append("&amp;lt;li&amp;gt;&amp;lt;pre&amp;gt;" + response.message + "&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;");
    });
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;...and some supporting HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label for="user-input"&amp;gt;Type a message to encrypt and send:&amp;lt;/label&amp;gt;
&amp;lt;textarea id="user-input"&amp;gt;&amp;lt;/textarea&amp;gt;
&amp;lt;button id="send-it" type="button"&amp;gt;Send Encrypted Message&amp;lt;/button&amp;gt;
&amp;lt;hr /&amp;gt;
&amp;lt;ol id="output"&amp;gt;&amp;lt;/ol&amp;gt;

&amp;lt;script type="text/javascript"&amp;gt;
$("#send-it").on('click', sendEncryptedMessage);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  PHP Decryption with Sodium
&lt;/h3&gt;

&lt;p&gt;You're going to want &lt;a href="https://github.com/paragonie/sodium_compat"&gt;paragonie/sodium_compat&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're using PHP 7.2, with overwhelming probability you can just use the built in &lt;code&gt;sodium_*&lt;/code&gt; functions. However, some distros &lt;em&gt;may&lt;/em&gt; incorrectly disable the sodium extension by default. So to play it safe, install sodium_compat anyway.&lt;/p&gt;

&lt;p&gt;If you're using a framework (Symfony, Laravel), your code will look a lot cleaner, but for the sake of illustration, the decryption code will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
declare(strict_types=1);

require 'vendor/autoload.php'; // Composer

header('Content-Type: application/json');

$key = sodium_hex2bin('e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0');

$encrypted = $_POST['message'] ?? null;
if (!$encrypted) {
    echo json_encode(
        ['message' =&amp;gt; null, 'error' =&amp;gt; 'no message provided'],
        JSON_PRETTY_PRINT
    );
    exit(1);
}

$nonce = sodium_hex2bin(substr($encrypted, 0, 48));
$ciphertext = sodium_hex2bin(substr($encrypted, 48));
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

echo json_encode(
    ['message' =&amp;gt; $plaintext, 'original' =&amp;gt; $encrypted],
    JSON_PRETTY_PRINT
);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Putting it Together
&lt;/h3&gt;

&lt;p&gt;When you type in a message and press the button, it will encrypt it and send a hex-encoded string to the server.&lt;/p&gt;

&lt;p&gt;The PHP code will then decrypt the message and return the plaintext in a JSON response.&lt;/p&gt;

&lt;p&gt;The JavaScript code will then grab the plaintext from the JSON response and append it to the output field below the form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;This is just a toy example to illustrate how to use &lt;a href="https://github.com/paragonie/sodium-plus"&gt;sodium-plus&lt;/a&gt; (JavaScript) and libsodium (PHP) to encrypt/decrypt messages.&lt;/p&gt;

&lt;p&gt;We took &lt;em&gt;a lot&lt;/em&gt; of shortcuts that you won't want to take in a real system (for example: hard-coding the encryption keys, and eschewing error-checking in favor of brevity).&lt;/p&gt;

&lt;p&gt;If you'd like to do something more advanced (&lt;a href="https://github.com/paragonie/sodium-plus/blob/master/docs/SodiumPlus/sealed-boxes.md"&gt;public-key encryption in JavaScript&lt;/a&gt; and the &lt;a href="https://paragonie.com/book/pecl-libsodium/read/08-advanced.md#crypto-box-seal"&gt;congruent PHP functions&lt;/a&gt;), the documentation is available for free online.&lt;/p&gt;

&lt;p&gt;Shameless plug: If you're looking for security experts to review your JavaScript or PHP code, check out &lt;a href="https://paragonie.com/blog/2017/06/why-you-want-paragon-initiative-enterprises-audit-your-code"&gt;why you may want to hire Paragon Initiative Enterprises for code audits&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful"&gt;The dangers of browser JavaScript cryptography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://paragonie.com/blog/2019/10/improving-cryptography-javascript-ecosystem"&gt;Improving the Cryptography of the JavaScript Ecosystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/paragonie/sodium-plus-a-positive-cryptography-experience-for-javascript-developers-2p08"&gt;Sodium-Plus: A Positive Cryptography Experience for JavaScript Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>javascript</category>
      <category>node</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>Sodium-Plus: A Positive Cryptography Experience for JavaScript Developers</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Mon, 07 Oct 2019 11:20:51 +0000</pubDate>
      <link>https://dev.to/paragonie/sodium-plus-a-positive-cryptography-experience-for-javascript-developers-2p08</link>
      <guid>https://dev.to/paragonie/sodium-plus-a-positive-cryptography-experience-for-javascript-developers-2p08</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Update (2019-10-11): I also published a &lt;a href="https://paragonie.com/blog/2019/10/improving-cryptography-javascript-ecosystem"&gt;follow-up to this article&lt;/a&gt; that's a bit broader in scope.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you ask around about implementing encryption or signatures in your apps, chances are someone will tell you to &lt;strong&gt;just use libsodium&lt;/strong&gt;. And this is, truthfully, the correct answer for most people's problems.&lt;/p&gt;

&lt;p&gt;However, the incumbent options for libsodium in the JavaScript ecosystem leave a &lt;em&gt;lot&lt;/em&gt; to be desired. &lt;/p&gt;

&lt;p&gt;In particular, there are two back-end libraries that implement libsodium in JavaScript that I'll be discussing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/sodium-friends/sodium-native"&gt;sodium-native&lt;/a&gt;, which is an unopinionated low-level binding of the C API&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jedisct1/libsodium.js"&gt;libsodium-wrappers&lt;/a&gt; (and the other packages in the &lt;code&gt;libsodium.js&lt;/code&gt; repository) which is cross-platform but slightly slower than sodium-native&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Encrypting a String in Sodium-Native
&lt;/h3&gt;

&lt;p&gt;I bet you think you could just do this and call it a day?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sodium-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize with random bytes:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is just an example string. Hello dev.to readers!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Encrypt:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Decrypt:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_open_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Short, sweet, and to the point, right? Nope. That code doesn't work at all.&lt;/p&gt;

&lt;p&gt;That snippet of code needs to be written like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sodium-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize with random bytes:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is just an example string. Hello dev.to readers!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Encrypt:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Decrypt:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_open_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This API is &lt;em&gt;terrible&lt;/em&gt; for JavaScript developers: Instead of returning a value, sodium-native overwrites one of the buffers you pass with the return value. Which means you have to allocate (and correctly size) buffers yourself.&lt;/p&gt;

&lt;p&gt;Manual buffer allocation, especially to Node.js devs who learned before &lt;code&gt;Buffer.alloc()&lt;/code&gt; and &lt;code&gt;Buffer.from()&lt;/code&gt; became the norm, almost begs developers to write memory unsafe code. It also breaks if the user provides a string input instead of a &lt;code&gt;Buffer&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encrypting a String in Libsodium.js
&lt;/h3&gt;

&lt;p&gt;Fortunately, &lt;code&gt;libsodium-wrappers&lt;/code&gt; does a fairly good job of exposing a usable in most cases. Except one caveat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;libsodium-wrappers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// You can't use the library until it's ready&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Henceforth, the API consists entirely of synchronous functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;libsodium-wrappers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_sodium&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Initialize with random bytes:&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is just an example string. Hello dev.to readers!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Encrypt:&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Decrypt:&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_open_easy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Other Differences and Design Warts
&lt;/h3&gt;

&lt;p&gt;Compared with sodium-native, libsodium-wrappers is slightly slower (sodium-native calls a C library, where as libsodium-wrappers compiles the library with emscripten), but it runs in more places (i.e. in web browsers) and doesn't need a C compiler to get running.&lt;/p&gt;

&lt;p&gt;Both libraries suffer from a subtle risk with X25519 keypairs: It's easy to accidentally get the public and secret key arguments mixed up and make your protocol insecure (although the unit tests will still pass).&lt;/p&gt;

&lt;p&gt;Neither library works well with IDE code completion.&lt;/p&gt;

&lt;p&gt;Neither library is particularly well-documented, either.&lt;/p&gt;

&lt;p&gt;Because of these grievances, if a developer asked me today which of the two to use in a greenfield development project, I wouldn't be able to recommend either. Which is really sad because &lt;a href="https://libsodium.gitbook.io/doc"&gt;the first two sentences of the official libsodium documentation&lt;/a&gt; state:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more.&lt;/p&gt;

&lt;p&gt;It is a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, with that in mind, I'd like to introduce Sodium-Plus to the world.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introducing Sodium-Plus (Na+)
&lt;/h1&gt;

&lt;h4&gt;
  
  
  You can find &lt;a href="https://github.com/paragonie/sodium-plus"&gt;sodium-plus on Github&lt;/a&gt; and &lt;a href="https://www.npmjs.com/package/sodium-plus"&gt;install it from NPM&lt;/a&gt;.
&lt;/h4&gt;

&lt;p&gt;Sodium-Plus is the libsodium API that JavaScript developers deserve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SodiumPlus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sodium-plus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Select a backend automatically&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SodiumPlus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_keygen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randombytes_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is just a test message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Message can be a string, buffer, array, etc.&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_secretbox_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid ciphertext throws instead of returning false.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;It's pluggable.&lt;/strong&gt; You can power it with either &lt;code&gt;sodium-native&lt;/code&gt; if you're strictly a Node shop and need the performance, or &lt;code&gt;libsodium-wrappers&lt;/code&gt; if you need cross-platform support. You can even install &lt;code&gt;sodium-native&lt;/code&gt; on some builds and Sodium-Plus will automatically use it in the default configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's asynchronous&lt;/strong&gt; where ever possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's fully type-safe.&lt;/strong&gt; You'll never accidentally get your public and secret keys mixed up with Sodium-Plus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SodiumPlus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sodium-plus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Select a backend automatically&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SodiumPlus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Selected backend: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBackendName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;aliceKeypair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_keypair&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;aliceSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_secretkey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aliceKeypair&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;alicePublic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_publickey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aliceKeypair&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// This works:&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alicePublic&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_seal_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alicePublic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aliceSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// These do not:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_seal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aliceSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sodium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;crypto_box_seal_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aliceSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alicePublic&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// TypeError { ... }&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Feel free to run this code yourself, both with and without &lt;code&gt;sodium-native&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;In virtually every way, we want Sodium-Plus to be an significant usability improvement over the existing libsodium implementations.&lt;/p&gt;

&lt;p&gt;Additionally, we want to make sure it's easier to use Sodium-Plus than any other JavaScript cryptography libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the Project Status?
&lt;/h2&gt;

&lt;p&gt;As of 2019-10-07:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Version 0.1.0 (the first alpha) has been released, which only contains the most common features of libsodium.&lt;/li&gt;
&lt;li&gt;Many APIs (&lt;code&gt;generichash&lt;/code&gt;, &lt;code&gt;secretstream&lt;/code&gt;, etc.) have not yet been implemented in our library. The documentation has not been completed yet for what is implemented.&lt;/li&gt;
&lt;li&gt;However, &lt;em&gt;your IDE will autocomplete&lt;/em&gt; correctly (due to our use of docblocks).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our development roadmap is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initial release. &lt;strong&gt;We are here.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Collect feedback from developers. (This is where I'd love your help!)&lt;/li&gt;
&lt;li&gt;API completeness. (a.k.a. Finish wrapping the other libraries)&lt;/li&gt;
&lt;li&gt;Complete the documentation.&lt;/li&gt;
&lt;li&gt;Ensure 100% unit test coverage.&lt;/li&gt;
&lt;li&gt;Ensure a &lt;code&gt;@types&lt;/code&gt; bundle is available for TypeScript users.&lt;/li&gt;
&lt;li&gt;Maybe get a security audit? (Not sure if the funding exists for this yet.)&lt;/li&gt;
&lt;li&gt;Version 1.0.0. (Expected late 2019.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where can I get Sodium-Plus?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Github: &lt;a href="https://github.com/paragonie/sodium-plus"&gt;https://github.com/paragonie/sodium-plus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NPM: &lt;a href="https://www.npmjs.com/package/sodium-plus"&gt;https://www.npmjs.com/package/sodium-plus&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cryptography</category>
      <category>security</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Case for Automatic Updates</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Wed, 31 Jan 2018 15:21:51 +0000</pubDate>
      <link>https://dev.to/paragonie/the-case-for-automatic-updates-477a</link>
      <guid>https://dev.to/paragonie/the-case-for-automatic-updates-477a</guid>
      <description>&lt;p&gt;Once a security bug exists in your customer's networks, preventing a security breach involves a lot of moving parts, but most importantly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identifying the security bugs before criminals do.&lt;/li&gt;
&lt;li&gt;Fixing the security bugs you've identified.&lt;/li&gt;
&lt;li&gt;Getting the patch deployed in all of your customer's networks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consider the timeline below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cFMr7W9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paragonie.com/files/blog/auto-updates.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cFMr7W9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paragonie.com/files/blog/auto-updates.png" title="The Life and Death of a Software Vulnerability. Time 0: Vulnerability Introduced; Time 1: Vulnerability Identified; Time 2: Vulnerability Fixed; Time 3: Fix deployed" alt="The Life and Death of a Software Vulnerability (Timeline)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The time between point 0 and point 1 might be years. For the Linux kernel, it's about 5 years on average. There are a lot of ways to reduce this number, and most of them involve automated testing and manual code review from security experts.&lt;/p&gt;

&lt;p&gt;The time between point 1 and point 2 might be weeks or months. Our average vulnerability identified-to-fixed time window is less than 24 hours. Most organizations do not enjoy the same agility or expertise.&lt;/p&gt;

&lt;p&gt;Most development teams have no control over the time between points 2 and 3 -- the amount of time it take for the fix to be applied (and the vulnerability to be neutralized) after the update is available.&lt;/p&gt;

&lt;p&gt;By making updates manual rather than automatic, you're forcing your customers to take all the responsibility for making sure that &lt;em&gt;your&lt;/em&gt; mistakes don't hurt their business. Only a very small minority of your customers might prefer the responsibility of verifying and applying each update themselves.&lt;/p&gt;

&lt;p&gt;By and large, most people do not have the security awareness, time management, and discipline to undertake this responsibility 24/7/365.&lt;/p&gt;

&lt;p&gt;Automatic security updates reduce the interval between points 2 and 3 from &lt;strong&gt;possibly infinite&lt;/strong&gt; to &lt;strong&gt;nearly zero.&lt;/strong&gt; That's clearly a meaningful improvement over manual patch management.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the Practical Risk in Outdated Software?
&lt;/h3&gt;

&lt;p&gt;The problem of outdated software is well-studied by the information security industry. According to &lt;a href="https://msisac.cisecurity.org/whitepaper/documents/1.pdf"&gt;Verizon's 2015 Data Breach Investigations Report (PDF)&lt;/a&gt;, for example, when a software vulnerability was used...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;99.9% of the exploited vulnerabilities were compromised &lt;em&gt;more than a year after the CVE was published&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In 2016, Wombat Security reflected on similar studies in an article titled &lt;a href="https://info.wombatsecurity.com/blog/out-of-date-software-and-plug-ins-compound-end-user-risk"&gt;Out-of-Date Software and Plug-ins Compound End-User Risk&lt;/a&gt;. An article on Help Net Security examines findings from F-Secure and echoes the problem of &lt;a href="https://www.helpnetsecurity.com/2014/04/02/the-dangers-of-using-outdated-software/"&gt;companies relying on out-dated software and putting their users at risk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The danger of outdated software is supported by both the data and by simple logic: If criminals are aware of a specific vulnerability in a software product, it doesn't matter that the vendor published a security patch if most of the companies that use their product will remain vulnerable when criminals want to exploit it.&lt;/p&gt;

&lt;h3&gt;
  
  
  It Seems So Obvious, But...
&lt;/h3&gt;

&lt;p&gt;If 99.9% of real-world software exploits are preventable by keeping software up-to-date, and the danger of unpatched vulnerabilities is well-known among security professionals, the obvious question is, "Why doesn't everything update itself automatically?"&lt;/p&gt;

&lt;p&gt;Implementing a secure automatic update mechanism is a nontrivial engineering feat that most programmers don't even know where to begin addressing. And often the ones that think they do are uninformed about the risks and complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple and Secure Automatic Software Updates
&lt;/h2&gt;

&lt;p&gt;First, make sure your deliverables are &lt;a href="https://reproducible-builds.org/"&gt;reproducible from the source code&lt;/a&gt;. If you're working with scripting languages that are never compiled into binary code, this merely requires your software be open source.&lt;/p&gt;

&lt;p&gt;Second, use an update framework (i.e &lt;a href="https://theupdateframework.github.io/"&gt;The Update Framework&lt;/a&gt;) that enforces code signing. This means that your update files must be signed by a private key controlled only by you, but can be verified by anyone with your public key.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't understand what "private key" or "public key" means, &lt;a href="https://dev.to/paragonie/you-wouldnt-base64-a-password-cryptography-terms-and-concepts-for-developers"&gt;our other dev.to article&lt;/a&gt; is an approachable introduction to cryptography terms and concepts and will shed some light on the matter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, run a &lt;a href="https://paragonie.com/blog/2017/07/chronicle-will-make-you-question-need-for-blockchain-technology"&gt;Chronicle&lt;/a&gt; instance. Every time you release an update, publish the new release information to your Chronicle. Make your code that interfaces with The Update Framework verify that the release you're seeing is also published in the Chronicle (or, especially for enterprise customers, their own replica of your Chronicle that resides on the corporate network).&lt;/p&gt;

&lt;p&gt;That's it. &lt;strong&gt;The Update Framework&lt;/strong&gt; (or a similar implementation relevant to your stack) and &lt;strong&gt;Chronicle&lt;/strong&gt; are all you need (as far as tooling goes). Make your software open source, and your builds reproducible, and you'll drastically reduce your customer's attack surface in terms of both space &lt;em&gt;and&lt;/em&gt; time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Automatic Software Updates in PHP
&lt;/h3&gt;

&lt;p&gt;There isn't currently a PHP implementation of The Update Framework. If there's enough community interest, we may commit to building one in the future. However, that might not be necessary.&lt;/p&gt;

&lt;p&gt;If you're developing modern PHP, you're almost certainly using Composer and Packagist. If not, it's &lt;a href="http://www.phptherightway.com/#composer_and_packagist"&gt;highly recommended that you learn it ASAP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In 2017, I opened a proposal to the &lt;a href="https://github.com/composer/packagist/issues/797"&gt;Packagist team&lt;/a&gt; to run their own Chronicle instance, which would be used to publish information about software releases in real time. We're working on other proposals to enforce signature validation and solve the Public Key Infrastructure (PKI) problems.&lt;/p&gt;

&lt;p&gt;In other words: If you're using Composer, then in the near future this may already be a solved problem for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Automatic Updates for Embedded Devices and the Internet of Things (IoT)
&lt;/h3&gt;

&lt;p&gt;Embedded development faces unique challenges and there hasn't been a lot of guidance on implementing secure automatic update protocols, especially for so-called "smart devices". Due to low memory or power usage requirements, it's often not feasible to just staple cryptography onto your product design without using up your entire power or memory budget.&lt;/p&gt;

&lt;p&gt;For extremely constrained devices, &lt;a href="https://github.com/jedisct1/libhydrogen"&gt;libhydrogen&lt;/a&gt; is an attractive option. It's very lightweight, and the current implementation uses only two primitives to provide a full-featured cryptography library: the Gimli permutation and Curve25519.&lt;/p&gt;




&lt;p&gt;This post merged the important parts of several posts about automatic updates on the &lt;a href="https://paragonie.com/blog"&gt;Paragon Initiative Enterprises blog&lt;/a&gt;. Check our website out if you're interested in &lt;a href="https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software"&gt;building secure PHP software&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>infosec</category>
      <category>appsec</category>
    </item>
    <item>
      <title>Supply Chain Attacks and Secure Software Updates</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Thu, 28 Sep 2017 13:26:08 +0000</pubDate>
      <link>https://dev.to/paragonie/supply-chain-attacks-and-secure-software-updates-ca0</link>
      <guid>https://dev.to/paragonie/supply-chain-attacks-and-secure-software-updates-ca0</guid>
      <description>

&lt;p&gt;I generally don't like writing about current events, because the inherent ephemeral nature of the news means that your words become less meaningful with each passing day. As a professional, I find wasting other people's time in poor taste.&lt;/p&gt;

&lt;p&gt;However, the topic of supply chain attacks has come up repeatedly in the recent months, so I'd like to take a moment to reflect on these incidents, as well as the work I've done through &lt;a href="https://paragonie.com"&gt;Paragon Initiative Enterprises&lt;/a&gt; (PIE for short) to be able to solve this problem at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's a Supply Chain Attack?
&lt;/h2&gt;

&lt;p&gt;In general, a supply chain attack involves first hacking a trusted third party who provides a product or service to your target, and then using your newly acquired, privileged position to compromise your intended target.&lt;/p&gt;

&lt;p&gt;More narrowly, we're only interested in supply chain attacks which involve compromising the companies that produce software used by other companies. Hardware based supply chain attacks have been demonstrated by leaked documents concerning nation state actors.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Recent History of Supply Chain Attacks
&lt;/h2&gt;

&lt;p&gt;Rather than rehash the long history of supply-chain attacks (both theoretical and actual) and the motivation for virtually every Linux distro to PGP-sign their update information, let's just look at what's happened in the year 2017.&lt;/p&gt;

&lt;p&gt;The industry's first wake-up call in recent months was a ransomware called NotPetya that was spread throughout Ukraine through &lt;a href="https://www.cyberscoop.com/petya-ransomware-medoc-hacked-auto-update/"&gt;the auto-update mechanism for &lt;em&gt;M.E.Doc&lt;/em&gt;, one of the few government-approved accounting softwares&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Last month, Kaspersky Lab's research teams published a write-up about a &lt;a href="https://www.kaspersky.com/about/press-releases/2017_shadowpad-how-attackers-hide-backdoor-in-software-used-by-hundreds-of-large-companies-around-the-world"&gt;malware campaign called ShadowPad&lt;/a&gt;, which infected a software update for an unspecified product by a company called &lt;a href="https://www.netsarang.com/"&gt;NetSarang&lt;/a&gt;. The product in question is reportedly used by hundreds of large firms, especially in the energy sector, so the long-term impact of such an infection (if undetected) is best left to the imagination.&lt;/p&gt;

&lt;p&gt;Most recently, but certainly not finally, we learned that the most recent updates for a common Windows utility called &lt;a href="https://techcrunch.com/2017/09/21/ccleaner-supply-chain-malware-targeted-tech-giants/"&gt;CCleaner had also been infected with malware&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Common Denominator in Recent Supply-Chain Attacks
&lt;/h3&gt;

&lt;p&gt;In each of these recent cases, malicious actors had compromised a software company and infected the "legitimate" copy of the software that users would download and install.&lt;/p&gt;

&lt;p&gt;In some of these cases, an automatic update mechanism was used to deliver the payloads. However, it is erroneous to call out auto-update features as the reason for infection. If a malicious and signed binary was uploaded to a company website, the fact that updates have to be performed manually would not have helped the victims. They would just happily install it, none the wiser.&lt;/p&gt;

&lt;p&gt;In all of these cases, the malicious software update was spread to everyone who installed it, rather than a targeted attack against only networks of interest. I'd wager that there are some of these going on in the wild as I type this, but they're inherently much more difficult to detect.&lt;/p&gt;

&lt;p&gt;The real security problem here has very little to do with automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fundamental Problem with Software Update Security
&lt;/h2&gt;

&lt;p&gt;The reason that supply chain attacks are viable, effective, and often difficult to detect is that &lt;em&gt;very little&lt;/em&gt; (if any) industry attention is given towards guaranteeing &lt;a href="https://defuse.ca/triangle-of-secure-code-delivery.htm"&gt;Software Authenticity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a topic we have covered extensively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://paragonie.com/blog/2017/08/quick-guide-simple-and-secure-automatic-updates"&gt;Quick and dirty guide to secure automatic updates&lt;/a&gt; (August 2017)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paragonie.com/blog/2016/10/guide-automatic-security-updates-for-php-developers"&gt;A technical tutorial on the ins and outs of automatic update implementations for PHP developers&lt;/a&gt; (October 2016)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paragonie.com/blog/2016/05/keyggdrasil-continuum-cryptography-powering-cms-airship"&gt;A detailed write-up of the implementation in our Free Software content management system, CMS Airship&lt;/a&gt; (May 2016)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paragonie.com/blog/2015/04/introducing-asgard-authentic-software-guard"&gt;Our very first blog post introduced &lt;em&gt;Asgard&lt;/em&gt;, our first attempt to solve this problem for the PHP community&lt;/a&gt; (April 2015)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you read only one of the above links, read the one from August 2017.&lt;/p&gt;

&lt;p&gt;Our company has done a lot of work in between client engagements to make it easier for developers to make their software updates &lt;strong&gt;signed&lt;/strong&gt;, &lt;strong&gt;auditable&lt;/strong&gt;, and &lt;strong&gt;reproducible&lt;/strong&gt;. This does several things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Signed:&lt;/strong&gt; If the signing key is kept offline, even if the webserver or update server is compromised,  the malware will not be accepted by the end user's computer. This is a nontrivial impediment to supply chain attacks, provided the company in question has adequate discipline to keep their signing key secret.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditable:&lt;/strong&gt; Even with a pilfered signing key, with this guarantee in place, attacks will be unavoidably detectable due to each update being committed to an append-only data structure (e.g. a Merkle tree or hash chain). This also ensures that everyone gets the same update and prevents targeted attacks (which, as mentioned above, haven't yet been detected, but cannot be ruled out).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible:&lt;/strong&gt; With open source software and reproducible builds, users can verify that the binary they received corresponds to the expected version of the software they intended to install. Combined with the auditability guarantee, if even one power user or security expert inspects the source code for backdoors, that's sufficient to ensure that all other copies of the same update are authentic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all three guarantees are provided, it's even &lt;a href="https://paragonie.com/blog/2016/10/guide-automatic-security-updates-for-php-developers#why-automatic-updates"&gt;generally safer to deploy your updates automatically&lt;/a&gt; (by default; power users should be allowed to disable this mechanism).&lt;/p&gt;

&lt;p&gt;Furthermore, because of these guarantees, most attackers will be dis-incentivized to even attempt such an attack: The success of their campaign hinges on their ability to steal a cryptography key, they can't target networks or persons of interest, the likelihood of being caught very early is extraordinarily high.&lt;/p&gt;

&lt;p&gt;If we can make all software updates come with authenticity guarantees, I believe we will all-but-eliminate supply chain attacks in the real world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does This Really Matter?
&lt;/h2&gt;

&lt;p&gt;We've consistently focused on the problem of ensuring software updates are secure enough to automate since our company's inception.&lt;/p&gt;

&lt;p&gt;We strongly believe that solving this problem at scale will have a more profound impact on the security of the Internet than &lt;em&gt;almost any other problem in all of information security and applied cryptography&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Wait, I Think I Can Solve This Using [Buzzword]"
&lt;/h3&gt;

&lt;p&gt;If you're looking for a killer app cybersecurity solution to these sort of attacks, the answer involves a lot of inglorious janitorial work &lt;a href="https://meta.stackoverflow.com/questions/293930/problematic-php-cryptography-advice-in-popular-questions"&gt;cleaning up the software ecosystem&lt;/a&gt; and &lt;a href="https://github.com/composer/packagist/issues/797"&gt;assisting open source software projects&lt;/a&gt; to get on board with scalable and trustworthy solutions.&lt;/p&gt;

&lt;p&gt;This is &lt;a href="https://paragonie.com/blog/2017/07/chronicle-will-make-you-question-need-for-blockchain-technology"&gt;not a problem that necessarily needs a blockchain&lt;/a&gt; to solve.&lt;/p&gt;

&lt;p&gt;It's not a problem that traditional endpoint security (read: anti-virus software) is even in the correct &lt;em&gt;genre&lt;/em&gt; to a solution.&lt;/p&gt;

&lt;p&gt;No, we're going to need to solve this as a community, not an industry. That means a lot of dedicated security experts and developers working together. That means a lot of short-term developer hours expended to improve the long-term health of your companies.&lt;/p&gt;

&lt;p&gt;I fully anticipate that &lt;a href="http://attrition.org/errata/charlatan/"&gt;charlatans and snake-oil salesmen&lt;/a&gt; will come out of the woodwork to pitch their poorly thought-out solutions to supply chain attacks as increasing number of computer criminals find them to be an effective way to infect victims. Even more hours will likely be expended on debunking their fraudulent claims and alerting the uninformed of their deception.&lt;/p&gt;

&lt;p&gt;But in the end? If we, as a community—as a society—can work together to solve the problem of secure software updates for the Internet at large? It will all be worth it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This was originally published on the &lt;a href="https://paragonie.com/blog/2017/09/supply-chain-attacks-and-secure-software-updates"&gt;PIE blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


</description>
      <category>supplychainattack</category>
      <category>softwareupdates</category>
      <category>cryptography</category>
      <category>automaticupdates</category>
    </item>
    <item>
      <title>Libsodium Quick Reference</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Mon, 19 Jun 2017 07:44:53 +0000</pubDate>
      <link>https://dev.to/paragonie/libsodium-quick-reference</link>
      <guid>https://dev.to/paragonie/libsodium-quick-reference</guid>
      <description>&lt;p&gt;If you're not familiar with cryptography terminology, &lt;a href="https://dev.to/paragonie/you-wouldnt-base64-a-password-cryptography-terms-and-concepts-for-developers"&gt;read this page first&lt;/a&gt;. It covers everything from terms (e.g. &lt;em&gt;nonce&lt;/em&gt;) to concepts (e.g. &lt;em&gt;public-key encryption&lt;/em&gt;). &lt;/p&gt;




&lt;p&gt;At &lt;a href="https://daycamp4developers.com"&gt;Day Camp 4 Developers&lt;/a&gt;, I presented a talk titled &lt;em&gt;Cooking with Sodium in PHP 7.2&lt;/em&gt;, which was largely live-demoing the various cryptography features provided by libsodium. One of the questions I was asked by attendees was about knowing which feature to use to solve specific problems. This is the sort of problem that I suspect many people run into, so here's a quick reference table followed by a detailed explanation.&lt;/p&gt;

&lt;p&gt;In the table below, all encryption modes utilize &lt;a href="https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly"&gt;authenticated encryption&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Libsodium Function&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Notes / Use Case&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tfoot&gt;&lt;tr&gt;
&lt;th&gt;Libsodium Function&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Notes / Use Case&lt;/th&gt;
&lt;/tr&gt;&lt;/tfoot&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_pwhash&lt;/td&gt;
  &lt;td&gt;Password hashing&lt;/td&gt;
  &lt;td&gt;Secure password storage, key derivation from user input&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_generichash&lt;/td&gt;
  &lt;td&gt;Cryptographic hash function&lt;/td&gt;
  &lt;td&gt;Collision- and preimage-resistant; replace MD5/SHA1/etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_shorthash&lt;/td&gt;
  &lt;td&gt;Short-input hash function&lt;/td&gt;
  &lt;td&gt;Hash tables, bloom filters, cache lookup keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_auth&lt;/td&gt;
  &lt;td&gt;Symmetric authentication&lt;/td&gt;
  &lt;td&gt;Both parties can verify and/or forge messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_sign&lt;/td&gt;
  &lt;td&gt;Asymmetric authentication&lt;/td&gt;
  &lt;td&gt;Digital signature (anyone can verify, only sender can sign)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_aead_*&lt;/td&gt;
  &lt;td&gt;Symmetric encryption&lt;/td&gt;
  &lt;td&gt;Shared-secret encryption with additional data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_secretbox&lt;/td&gt;
  &lt;td&gt;Symmetric encryption&lt;/td&gt;
  &lt;td&gt;Compatibility with NaCl, TweetNaCl, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_box&lt;/td&gt;
  &lt;td&gt;Asymmetric encryption&lt;/td&gt;
  &lt;td&gt;Both sender and receiver can decrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;crypto_box_seal&lt;/td&gt;
  &lt;td&gt;Asymmetric encryption&lt;/td&gt;
  &lt;td&gt;Only receiver can decrypt; sender is anonymous&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Solving Common Tasks with Libsodium
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;I need to store an encrypted or hashed password (&lt;a href="https://paragonie.com/blog/2015/08/you-wouldnt-base64-a-password-cryptography-decoded#passwords"&gt;actually never encrypted, only hashed&lt;/a&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;crypto_pwhash_str()&lt;/code&gt; and &lt;code&gt;crypto_pwhash_str_verify()&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I need to encrypt a string and then decrypt it later (on the &lt;em&gt;same&lt;/em&gt; machine)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For simplicity: use &lt;code&gt;crypto_secretbox()&lt;/code&gt; and &lt;code&gt;crypto_secretbox_open()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's actually better to use &lt;code&gt;crypto_aead_*&lt;/code&gt; (especially if you use the sample code, but the &lt;code&gt;secretbox&lt;/code&gt; API is simple and secure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I need to encrypt a string and then decrypt it later (on a &lt;em&gt;different&lt;/em&gt; machine)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It depends!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do you have a two-way data flow (&lt;code&gt;A &amp;lt;=&amp;gt; B&lt;/code&gt;) or a one-way data flow (&lt;code&gt;A -&amp;gt; B&lt;/code&gt;)?&lt;/p&gt;

&lt;p&gt;If you're only ever encrypting on Node A, and only ever decrypting on Node B, you'll want &lt;code&gt;crypto_box_seal()&lt;/code&gt; and &lt;code&gt;crypto_box_seal_open()&lt;/code&gt;. This prevents the sender (Node A) from decrypting messages after they've been sent to recipient (Node B).&lt;/p&gt;

&lt;p&gt;Otherwise, you'll simply want to use &lt;code&gt;crypto_box()&lt;/code&gt; and &lt;code&gt;crypto_box_open()&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I previously used mcrypt_encrypt() or openssl_encrypt() and need to migrate my data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, decrypt your data as usual, then re-encrypt using &lt;code&gt;crypto_secretbox()&lt;/code&gt; and &lt;code&gt;crypto_secretbox_open()&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I previously used openssl_public_encrypt() / openssl_private_decrypt() and need to migrate my data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, decrypt your data as usual, then re-encrypt using &lt;code&gt;crypto_box&lt;/code&gt; or &lt;code&gt;crypto_box_seal&lt;/code&gt; (see previous answer about encryption between different machines for guidance on which one you want).&lt;/p&gt;

&lt;h1&gt;
  
  
  Libsodium Function Analysis
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;PHP Developers:&lt;/strong&gt; In PHP before 7.2 with libsodium from PECL, the functions below were defined in the &lt;code&gt;Sodium&lt;/code&gt; name space. In PHP 7.2, the namespaces were dropped in favor of a &lt;code&gt;sodium_&lt;/code&gt; prefix (to conform to the PHP internal development standards).&lt;/p&gt;

&lt;p&gt;For example, in PHP 7.1 and below with ext/sodium from PECL, an example snippet for &lt;code&gt;crypto_secretbox()&lt;/code&gt; might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// PHP &amp;lt; 7.2 with `pecl install libsodium`
$key = str_repeat("\x80", 32);
$nonce = random_bytes(24);
$data = $nonce . \Sodium\crypto_secretbox("Test", $nonce, $key);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When PHP 7.2 is released, the interface will look like this instead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// PHP &amp;gt;= 7.2
$key = str_repeat("\x80", 32);
$nonce = random_bytes(24);
$data = $nonce . sodium_crypto_secretbox("Test", $nonce, $key);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For &lt;a href="https://github.com/paragonie/sodium_compat"&gt;sodium_compat&lt;/a&gt; users, your code will look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// PHP &amp;gt;= 7.2
$key = str_repeat("\x80", 32);
$nonce = random_bytes(24);
$data = $nonce . ParagonIE_Sodium_Compat::crypto_secretbox("Test", $nonce, $key);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the examples below, when we define a libsodium function, the actual function name will be either namespaced, prefixed, or a static method on &lt;code&gt;ParagonIE_Sodium_Compat&lt;/code&gt;. For simplicity, we're using the bare libsodium name since that part remains constant.&lt;/p&gt;

&lt;h2 id="hash-functions"&gt;Hash Functions&lt;/h2&gt;

&lt;h3 id="crypto-pwhash"&gt;crypto_pwhash()&lt;/h3&gt;

&lt;p&gt;Choose your own adventure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key derivation: &lt;code&gt;crypto_pwhash()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password hashing/verification: &lt;code&gt;crypto_pwhash_str()&lt;/code&gt; and &lt;code&gt;crypto_pwhash_str_verify()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Libsodium uses Argon2, the &lt;a href="https://password-hashing.net"&gt;Password Hashing Competition&lt;/a&gt; winner. More specifically, it uses Argon2i (the side-channel resistant variant) in all current versions, but a future version may switch the default to Argon2id, which is more resistant to GPU attacks.&lt;/p&gt;

&lt;p&gt;You want to use one of the &lt;code&gt;crypto_pwhash&lt;/code&gt; functions whenever you are taking a &lt;strong&gt;user-provided input&lt;/strong&gt; (i.e a password) and your goal is to either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;turn their password into a cryptography key, or&lt;/li&gt;
&lt;li&gt;store it for secure verification at a later date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure you check &lt;a href="https://download.libsodium.org/doc/password_hashing"&gt;the official libsodium documentation covering &lt;code&gt;crypto_pwhash&lt;/code&gt;&lt;/a&gt; for details on how to use it.&lt;/p&gt;

&lt;h4 id="crypto-pwhash-sample-php"&gt;crypto_pwhash() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php

/* This uses Argon2i with two numeric constants that correspond to
 * the number of passes (OPSLIMIT) and the amount of memory to use
 * (MEMLIMIT). A higher OPSLIMIT helps against CPU attacks, while a
 * higher MEMLIMIT helps against GPU attacks.
 */
$storeInDatabase = sodium_crypto_pwhash_str(
    $password, 
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

/* Once that's stored, you can just test against the hash like so: */
if (sodium_crypto_pwhash_str_verify($password, $storeInDatabase)) {
    /* Logged in! */
} else {
    /* Incorrect password. */
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-generichash"&gt;crypto_generichash()&lt;/h3&gt;

&lt;p&gt;For PHP developers: This is sort of like &lt;code&gt;hash()&lt;/code&gt;, except it can also be &lt;code&gt;hash_hmac()&lt;/code&gt; if you pass a key, and it only allows BLAKE2b (so you don't have to select the algorithm).&lt;/p&gt;

&lt;p&gt;You want to use &lt;code&gt;crypto_generichash()&lt;/code&gt; anywhere you'd normally use &lt;code&gt;hash()&lt;/code&gt;, &lt;code&gt;md5()&lt;/code&gt;, or &lt;code&gt;sha1()&lt;/code&gt; (unless "normally" implies something that would cause a cryptographer would look at you funny). &lt;code&gt;crypto_generichash()&lt;/code&gt; is attractive because it is all of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collision-resistant&lt;/li&gt;
&lt;li&gt;Preimage-resistant&lt;/li&gt;
&lt;li&gt;Immune to length-extension attacks&lt;/li&gt;
&lt;li&gt;More secure than SHA256&lt;/li&gt;
&lt;li&gt;Faster than MD5&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See also: &lt;a href="https://download.libsodium.org/doc/hashing/generic_hashing.html"&gt;the libsodium documentation on &lt;code&gt;crypto_generichash&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="crypto-generichash-sample-php"&gt;crypto_generichash() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php

$someData = 'This is a test message';
$someSecretKey = random_bytes(32);

$hash      = sodium_crypto_generichash($someData);
var_dump(mb_strlen($hash, '8bit')); /* int(32) */

$blake2mac = sodium_crypto_generichash($someData, $someSecretKey);
var_dump(mb_strlen($blake2mac, '8bit')); /* int(32) */

$truncated = sodium_crypto_generichash($someData, '', 16);
var_dump(mb_strlen($truncated, '8bit')); /* int(16) */&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-shorthash"&gt;crypto_shorthash()&lt;/h3&gt;

&lt;p&gt;SipHash, the algorithm powering &lt;code&gt;crypto_shorthash()&lt;/code&gt;, is a secure keyed pseudo-random function. Or, in other words, it's a hash function like BLAKE2b, except it's only meant to be used with a key and its output size of 64 bits is too small to be collision-resistant or immune to brute-force searches.&lt;/p&gt;

&lt;p&gt;Don't use &lt;code&gt;crypto_shorthash()&lt;/code&gt; in places where &lt;code&gt;crypto_generichash()&lt;/code&gt; would be appropriate. SipHash is better suited for building hash tables with a per-request key to resist hash-collision denial-of-service attacks. You can also use it for Bloom filters and cache lookups where micro-benchmarks matter. But generally, &lt;code&gt;crypto_generichash()&lt;/code&gt; and &lt;code&gt;crypto_pwhash()&lt;/code&gt; are probably better tools for the job.&lt;/p&gt;

&lt;p&gt;See also: &lt;a href="https://download.libsodium.org/doc/hashing/short-input_hashing.html"&gt;the libsodium documentation on &lt;code&gt;crypto_shorthash&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="crypto-shorthash-sample-php"&gt;crypto_shorthash() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$key = random_bytes(16);
$input = ['apple', 'boy', 'cat', 'dog', 'echo'];
$mapped = [];
foreach ($input as $item) {
    $hash = sodium_crypto_shorthash($item, $key);
    $mapped[bin2hex($hash)] = $item;
}
var_dump($mapped);&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="authentication"&gt;Authentication&lt;/h2&gt;

&lt;h3 id="crypto-auth"&gt;crypto_auth()&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;crypto_auth()&lt;/code&gt; is from NaCl, and serves to provide symmetric-key authentication. If you know about HMAC, you know what this does. PHP developers will only really only need &lt;code&gt;crypto_auth()&lt;/code&gt; and its counterpart &lt;code&gt;crypto_auth_verify()&lt;/code&gt; if you're aiming to interoperate with other NaCl/libsodium projects. Otherwise, &lt;code&gt;hash_hmac()&lt;/code&gt; and &lt;code&gt;hash_equals()&lt;/code&gt; accomplish the same thing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;crypto_auth()&lt;/code&gt; is, in fact, HMAC-SHA512 truncated to 32 bytes.&lt;/p&gt;

&lt;p&gt;It is important to note that, with HMAC, any party capable of verifying messages is also capable of signing them. That's what symmetric-key authentication means. If you need one entity to be able to sign, but everyone else in the universe to be able to only verify, then you want &lt;code&gt;crypto_sign()&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;See also: &lt;a href="https://download.libsodium.org/doc/secret-key_cryptography/secret-key_authentication.html"&gt;the libsodium documentation on &lt;code&gt;crypto_auth&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="crypto-auth-sample-php"&gt;crypto_auth() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$key = random_bytes(32);
$message = 'authenticate me';

/* Get the message authentication code (MAC): */
$mac = sodium_crypto_auth($message, $key);

/* Verify a message: */
if (sodium_crypto_auth_verify($mac, $message, $key)) {
    /* Verified */
} else {
    /* Message has been tampered with; discard */
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-sign"&gt;crypto_sign()&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;crypto_sign&lt;/code&gt; functions come in two flavors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;crypto_sign()&lt;/code&gt; and &lt;code&gt;crypto_sign_open()&lt;/code&gt;, which are useful for sending signed messages in one go.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crypto_sign_detached()&lt;/code&gt; and &lt;code&gt;crypto_sign_verify_detached()&lt;/code&gt;, which are more generally useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally, you'll find yourself reaching for the latter two more in PHP land, but the original two are useful too.&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;crypto_auth&lt;/code&gt;, &lt;code&gt;crypto_sign&lt;/code&gt; utilizes &lt;em&gt;asymmetric&lt;/em&gt; (a.k.a. &lt;em&gt;public-key&lt;/em&gt;) cryptography. You sign a message with your secret key, and anyone with your public key can verify the message.&lt;/p&gt;

&lt;p&gt;Once again, the libsodium &lt;a href="https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html"&gt;documentation for &lt;code&gt;crypto_sign&lt;/code&gt;&lt;/a&gt; is worth a read.&lt;/p&gt;

&lt;h4 id="crypto-sign-sample-php"&gt;crypto_sign() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$mySigningKeypair = sodium_crypto_sign_keypair();
$secretKey = sodium_crypto_sign_secretkey($mySigningKeypair);
$publicKey = sodium_crypto_sign_publickey($mySigningKeypair);

$message = 'authenticate me';

/* Sign the message, using your secret key (which is NOT given out): */
$signature = sodium_crypto_sign_detached($message, $secretKey);

/* Now validate the signature with your public key (which IS given out): */
if (sodium_crypto_sign_verify_detached($signature, $message, $publicKey)) {
    /* Message was signed by me. */
} else {
    throw new Exception('Invalid signature. Do not trust the message.');
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="encryption"&gt;Encryption&lt;/h2&gt;

&lt;h3 id="crypto-aead"&gt;crypto_aead()&lt;/h3&gt;

&lt;p&gt;AEAD is a cryptographer acronym that stands for &lt;strong&gt;A&lt;/strong&gt;uthenticated &lt;strong&gt;E&lt;/strong&gt;ncryption with &lt;strong&gt;A&lt;/strong&gt;ssociated &lt;strong&gt;D&lt;/strong&gt;ata. The general idea is that you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your plaintext, which gets encrypted into the ciphertext.&lt;/li&gt;
&lt;li&gt;Some other data, which doesn't touch the ciphertext.&lt;/li&gt;
&lt;li&gt;An authentication tag, which covers both the ciphertext and the other data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You want to use &lt;code&gt;crypto_aead&lt;/code&gt; when you have either a pre-shared key or a negotiated one (e.g. via Elliptic Curve Diffie-Hellman).&lt;/p&gt;

&lt;p&gt;AEAD modes are the preferred way to encrypt in 2017. Libsodium offers several options for its AEAD interface, all of which implement symmetric encryption. You will probably want to use, in order of preference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(One day): &lt;code&gt;crypto_aead_encrypt()&lt;/code&gt; and &lt;code&gt;crypto_aead_decrypt()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Not available yet.&lt;/li&gt;
&lt;li&gt;Will be available after the selection of &lt;a href="https://competitions.cr.yp.to/caesar.html"&gt;CAESAR&lt;/a&gt; finalists.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crypto_aead_xchacha20poly1305_ietf_*()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to use very large nonces, which can safely be generated randomly with no practical risk of accidental nonce reuse.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crypto_aead_chacha20poly1305_ietf_*()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;The standardized ChaCha20-Poly1305 variant.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crypto_aead_aes256gcm_*()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Required specialized hardware support. Only use this if every device is guaranteed to have modern processors.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crypto_aead_chacha20poly1305_*()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Implemented before the IETF standardized their nonce/counter sizes for use in TLS. Less widely supported.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://download.libsodium.org/doc/secret-key_cryptography/aead.html"&gt;AEAD section of the libsodium documentation&lt;/a&gt; has more details about key/nonce sizes, etc.&lt;/p&gt;

&lt;h4 id="crypto-aead-sample-php"&gt;crypto_aead_*() Sample Code (PHP with sodium_compat)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * Wrap crypto_aead_*_encrypt() in a drop-dead-simple encryption interface
 *
 * @link https://paragonie.com/b/kIqqEWlp3VUOpRD7
 * @param string $message
 * @param string $key
 * @return string
 */
function simpleEncrypt($message, $key)
{
    $nonce = random_bytes(24); // NONCE = Number to be used ONCE, for each message
    $encrypted = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt(
        $message,
        $nonce,
        $nonce,
        $key
    );
    return $nonce . $encrypted;
}

/**
 * Wrap crypto_aead_*_decrypt() in a drop-dead-simple decryption interface
 *
 * @link https://paragonie.com/b/kIqqEWlp3VUOpRD7
 * @param string $message - Encrypted message
 * @param string $key     - Encryption key
 * @return string
 * @throws Exception
 */
function simpleDecrypt($message, $key)
{
    $nonce = mb_substr($message, 0, 24, '8bit');
    $ciphertext = mb_substr($message, 24, null, '8bit');
    $plaintext = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt(
        $ciphertext,
        $nonce,
        $nonce,
        $key
    );
    if (!is_string($plaintext)) {
        throw new Exception('Invalid message');
    }
    return $plaintext;
}

$secretKey = random_bytes(32);
$message = 'Test message';

/* Encrypt the message: */
$ciphertext = simpleEncrypt($message, $secretKey);

/* Decrypt the message: */
try {
    $decrypted = simpleDecrypt($ciphertext, $secretKey);
    var_dump(hash_equals($decrypted, $message));
    /* bool(true) */
} catch (Exception $ex) {
    /* Someone is up to no good */
    exit(255);
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-secretbox"&gt;crypto_secretbox()&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;crypto_secretbox()&lt;/code&gt; is from NaCl and implements symmetric (shared-key) authenticated encryption. &lt;code&gt;secretbox&lt;/code&gt; accepts a large nonce, which is safe to generate randomly (&lt;code&gt;random_bytes()&lt;/code&gt; in PHP, &lt;code&gt;randombytes_buf()&lt;/code&gt; in libsodium) and virtually never worry about reusing a nonce.&lt;/p&gt;

&lt;p&gt;You want to use &lt;code&gt;crypto_secretbox()&lt;/code&gt; when you have either a pre-shared key or a negotiated one (e.g. via Elliptic Curve Diffie-Hellman).&lt;/p&gt;

&lt;p&gt;If you have to choose between &lt;code&gt;secretbox&lt;/code&gt; and &lt;code&gt;aead_xchacha20poly1305&lt;/code&gt;, go for the AEAD mode. Otherwise, use &lt;code&gt;secretbox&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The relevant section of the libsodium documentation for &lt;code&gt;crypto_secretbox&lt;/code&gt; can be found &lt;a href="https://download.libsodium.org/doc/secret-key_cryptography/authenticated_encryption.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="crypto-secretbox-sample-php"&gt;crypto_secretbox_*() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$key = random_bytes(32);
$message = 'Yellow submarine';

/* For each encryption: */
    $nonce = random_bytes(24); /* Never repeat this! */
    $ciphertext = sodium_crypto_secretbox($message, $nonce, $key);
    $plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-box"&gt;crypto_box()&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;crypto_box&lt;/code&gt; is from NaCl and implements authenticated asymmetric (a.k.a. public-key) encryption. With &lt;code&gt;crypto_box()&lt;/code&gt;, both the sender and recipient can read messages and verify the other party sent them. However, it allows each party to negotiate their own private keys and share distinct secrets with each other, so talking with one person doesn't allow you to eavesdrop on another's conversations with them.&lt;/p&gt;

&lt;p&gt;You want to use &lt;code&gt;crypto_box()&lt;/code&gt; where you'd normally implement RSA encryption. It's more commonly found in interactive protocols (e.g. messaging applications).&lt;/p&gt;

&lt;p&gt;To learn more, see the &lt;a href="https://download.libsodium.org/doc/public-key_cryptography/authenticated_encryption.html"&gt;libsodium documentation for &lt;code&gt;crypto_box&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="crypto-box-sample-php"&gt;crypto_box() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
# Setup:

/* On Node A */
$aliceKeypair = sodium_crypto_box_keypair();
    $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeypair);
    $alicePublicKey = sodium_crypto_box_publickey($aliceKeypair);
    // Then share $alicePublicKey with Node B

/* On Node B: */
$bobKeypair = sodium_crypto_box_keypair();
    $bobSecretKey = sodium_crypto_box_secretkey($bobKeypair);
    $bobPublicKey = sodium_crypto_box_publickey($bobKeypair);
    // Then share $bobPublicKey with Node A

# Transmission:

/* Sending from Node A to Node B */
    $message 'Hi there! :)';
    $aliceToBob = $aliceSecretKey . $bobPublicKey;
    $nonce = random_bytes(24); /* Never repeat this! */
    $ciphertext = $nonce . sodium_crypto_box($message, $nonce, $aliceToBob);

/* On Node B, receiving an encrypted message from Node A */
    $bobToAlice = $bobSecretKey . $alicePublicKey;
    $nonce = mb_substr($ciphertext, 0, 24, '8bit');
    $encrypted = mb_substr($ciphertext, 24, null, '8bit');
    $decrypted = sodium_crypto_box_open($encrypted, $nonce, $bobToAlice);

# Alternatively:

/* Sending from Node B to Node A */
    $message 'Hello yourself.';
    $bobToAlice = $bobSecretKey . $alicePublicKey;
    $nonce = random_bytes(24); /* Never repeat this! */
    $ciphertext = $nonce . sodium_crypto_box($message, $nonce, $bobToAlice);

/* On Node A, receiving an encrypted message from Node B */
    $aliceToBob = $aliceSecretKey . $bobPublicKey;
    $nonce = mb_substr($ciphertext, 0, 24, '8bit');
    $encrypted = mb_substr($ciphertext, 24, null, '8bit');
    $decrypted = sodium_crypto_box_open($encrypted, $nonce, $aliceToBob);&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="crypto-box-seal"&gt;crypto_box_seal()&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;crypto_box_seal()&lt;/code&gt; is a libsodium exclusive, which allows the sender to encrypt a message that only the recipient can decrypt. Sealing APIs are sometimes referred to as &lt;strong&gt;anonymous public-key encryption&lt;/strong&gt;, because although it provides ciphertext integrity, the sender is not authenticated like with &lt;code&gt;crypto_box&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You want to use &lt;code&gt;crypto_box_seal&lt;/code&gt; whenever you're encrypting information that you don't want the sender to be able to decrypt. For example, storing encrypted data in an online database that can only be decrypted with key that is kept offline in an air-gapped machine.&lt;/p&gt;

&lt;p&gt;If you're trying to decide between &lt;code&gt;crypto_box()&lt;/code&gt; versus &lt;code&gt;crypto_box_seal()&lt;/code&gt;, ask yourself if the system that performed the encryption should be capable of decrypting the messages they sent. If the answer is no, you want &lt;code&gt;crypto_box_seal()&lt;/code&gt;. If you still need the sender to be authenticated, use &lt;code&gt;crypto_sign()&lt;/code&gt; before &lt;code&gt;crypto_box_seal()&lt;/code&gt; on the sending side and &lt;code&gt;crypto_sign_open()&lt;/code&gt; after &lt;code&gt;crypto_box_seal_open()&lt;/code&gt; on the receiving side.&lt;/p&gt;

&lt;p&gt;As always, &lt;a href="https://download.libsodium.org/doc/public-key_cryptography/sealed_boxes.html"&gt;the documentation for &lt;code&gt;crypto_box_seal&lt;/code&gt;&lt;/a&gt; explains its usage in-depth.&lt;/p&gt;

&lt;h4 id="crypto-box-seal-sample-php"&gt;crypto_box_seal() Sample Code (PHP 7.2+)&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
# Setup:

/* On Node B: */
$bobKeypair = sodium_crypto_box_keypair();
    $bobPublicKey = sodium_crypto_box_publickey($bobKeypair);
    // Then share $bobPublicKey with Node A

# Transmission:

/* Sending from Node A to Node B */
    $message 'Hi there! :)';
    $ciphertext = sodium_crypto_box_seal($message, $bobPublicKey);

/* On Node B, receiving an encrypted message from Node A */
    $decrypted = sodium_crypto_box_seal_open($ciphertext, $bobKeypair);&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;
  
  
  Other Functions
&lt;/h1&gt;

&lt;p&gt;If you're confused about any of the libsodium functions not listed here, refer to the &lt;a href="https://download.libsodium.org/doc/"&gt;official libsodium documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;This was originally published on &lt;a href="https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use"&gt;our company website&lt;/a&gt;. All of our blog posts are released under a Creative Commons License.&lt;/p&gt;

</description>
      <category>security</category>
      <category>crypto</category>
      <category>libsodium</category>
    </item>
    <item>
      <title>PHP 7.2: The First Programming Language to Add Modern Cryptography to its Standard Library</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Sun, 12 Feb 2017 22:36:34 +0000</pubDate>
      <link>https://dev.to/paragonie/php-72-the-first-programming-language-to-add-modern-cryptography-to-its-standard-library</link>
      <guid>https://dev.to/paragonie/php-72-the-first-programming-language-to-add-modern-cryptography-to-its-standard-library</guid>
      <description>

</description>
      <category>crypto</category>
      <category>cryptography</category>
      <category>nacl</category>
      <category>libsodium</category>
    </item>
    <item>
      <title>You Wouldn't Base64 a Password! Cryptography Terms and Concepts for Developers</title>
      <dc:creator>Scott Arciszewski</dc:creator>
      <pubDate>Tue, 13 Dec 2016 21:57:50 +0000</pubDate>
      <link>https://dev.to/paragonie/you-wouldnt-base64-a-password-cryptography-terms-and-concepts-for-developers</link>
      <guid>https://dev.to/paragonie/you-wouldnt-base64-a-password-cryptography-terms-and-concepts-for-developers</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at: &lt;a href="https://paragonie.com/blog/2015/08/you-wouldnt-base64-a-password-cryptography-decoded" rel="noopener noreferrer"&gt;You Wouldn't Base64 a Password! on the Paragon Initiative Enterprises blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's a ton of bad programming and security advice on the Internet. Some of the advice is bad because the author is misinformed, some because it emphasizes precision over clarity and most people wind up lost in the jargon.&lt;/p&gt;

&lt;p&gt;If you feel that cryptography is a weird, complicated, and slightly intimidating subject for which your feelings might be best described as lukewarm (on a good day), we hope that by the time you finish reading this page, you will have a clear understanding of the terms and concepts people use when this topic comes up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: The example snippets on this page are for illustrative purposes. Don't use them in your projects. If you want a real-world example to reference, check out &lt;a href="https://stackoverflow.com/a/30189841/2224584" rel="noopener noreferrer"&gt;the snippets in our Chief Development Officer's StackOverflow answer&lt;/a&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Basic Cryptography Concepts for Developers
&lt;/h1&gt;

&lt;p&gt;Let's start with a basic question: &lt;strong&gt;What exactly is a cryptographic feature?&lt;/strong&gt; In the simplest terms we can muster: &lt;code&gt;Cryptographic features use math to secure an application&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Digging a little deeper: there are a plethora of cryptography algorithms and they can generally be grouped together based on two criteria:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How much information must be supplied by the developer?&lt;/li&gt;
&lt;li&gt;What is the intended goal?

&lt;ul&gt;
&lt;li&gt;Confidentiality?&lt;/li&gt;
&lt;li&gt;Integrity?&lt;/li&gt;
&lt;li&gt;Authenticity?&lt;/li&gt;
&lt;li&gt;Non-repudiation? Deniability? (These two are opposites.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="overview"&gt;Overview of Cryptography Concepts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fparagonie.com%2Ffiles%2Fblog%2Fcrypto-categories.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fparagonie.com%2Ffiles%2Fblog%2Fcrypto-categories.png" alt="Categories of cryptographic and non-cryptographic concepts" title="Categories of cryptographic and non-cryptographic concepts" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyless Cryptography (0 keys)

&lt;ul&gt;
&lt;li&gt;Hash Functions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Secret-Key Cryptography (1 key)

&lt;ul&gt;
&lt;li&gt;Secret-Key Message Authentication&lt;/li&gt;
&lt;li&gt;Secret-Key Encryption&lt;/li&gt;
&lt;li&gt;Authenticated Secret-Key Encryption&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Public-Key Cryptography (2 keys)

&lt;ul&gt;
&lt;li&gt;Shared Secret Key Agreement&lt;/li&gt;
&lt;li&gt;Digital Signatures&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  The First Rule of Cryptography: Don't Implement it Yourself
&lt;/h2&gt;

&lt;p&gt;Developing cryptography features is best left to the experts. By all means, &lt;a href="http://www.cryptofails.com/post/75204435608/write-crypto-code-dont-publish-it" rel="noopener noreferrer"&gt;do feel free to tinker&lt;/a&gt;, but don't deploy your experiments in production or share them with other developers who might deploy them in production.&lt;/p&gt;

&lt;p&gt;Instead, use a high-level cryptography library that experts have already vetted. Follow the link to read our &lt;a href="https://paragonie.com/blog/2015/11/choosing-right-cryptography-library-for-your-php-project-guide" rel="noopener noreferrer"&gt;PHP cryptography library recommendations&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="hash-functions"&gt;Keyless Cryptography&lt;/h2&gt;

&lt;p&gt;The simplest algorithm to consider is the &lt;strong&gt;cryptographic hash function&lt;/strong&gt;, which accepts one input and returns a single deterministic fixed-size output.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash("sha256", "");
// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

hash("sha256", "The quick brown fox jumps over the lazy dog");
// d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When using a well-designed cryptographic hash function, such as &lt;strong&gt;BLAKE2&lt;/strong&gt; or SHA256, any change you make to the message will result in a drastically different hash output.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash("sha256", "The quick brown fox jumps over the lazy cog");
// e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Simple hash functions are fast and deterministic; if you have any arbitrary message, you can calculate the hash output for that particular message. By themselves, they are mostly useful for error checking or as a building block for other cryptographic primitives, which most developers will not need to develop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cryptographic hash functions are one-way data transformations.&lt;/strong&gt; Although you can easily calculate the hash output (often referred to as a message digest) for any arbitrary message, you cannot easily go from the hash output to the original message.&lt;/p&gt;

&lt;p&gt;Some hash functions (such as MD5) have weaker security guarantees and smaller output sizes. As a result, it's &lt;a href="http://natmchugh.blogspot.fr/2015/02/create-your-own-md5-collisions.html" rel="noopener noreferrer"&gt;almost trivial to calculate two different messages that will produce the same MD5 hash&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="secret-key"&gt;Secret Key Cryptography&lt;/h2&gt;

&lt;p&gt;Most cryptography algorithms aren't as simple as hash functions. As a consequence, they are a lot more useful and can provide security guarantees beyond, "Yes, this output can be reproduced from this input."&lt;/p&gt;

&lt;p&gt;Consequently, they typically require two pieces of input: The message and a &lt;strong&gt;secret key&lt;/strong&gt;. A secret key should be a unique string of random bytes that both the sender and intended recipient should know, and nobody else.&lt;/p&gt;

&lt;h3 id="mac"&gt;Keyed Hash Functions - Message Authentication&lt;/h3&gt;

&lt;p&gt;A keyed hash function, such as &lt;a href="https://en.wikipedia.org/wiki/Hash-based_message_authentication_code" rel="noopener noreferrer"&gt;HMAC&lt;/a&gt;, is a special implementation of a hash function that accepts a message and a secret key and produces a Message Authentication Code (MAC).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash_hmac("sha256", "The quick brown fox jumps over the lazy dog", "secret key");
// 4a513ac60b4f0253d95c2687fa104691c77c9ed77e884453c6a822b7b010d36f

hash_hmac("sha256", "The quick brown fox jumps over the lazy cog", "secret key");
// ed6b9bc9d64e4c923b2cc19c15fff329f343f30884935c10e617e0fe067adef1

hash_hmac("sha256", "The quick brown fox jumps over the lazy dog", "secret kez");
// 291579f3123c3126df04a57f78768b6290df93f979b86af25fecd98a9811da5a

hash_hmac("sha256", "The quick brown fox jumps over the lazy cog", "secret kez");
// 298bb0244ebc987810de3892384bb4663742a540db2b3a875f66b09d068d1f64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Keyed hash functions are more useful than hash functions; only someone with the secret key can calculate a MAC for a given message. Therefore, if you transmit a message and a MAC for a given message, and never transmit the secret key, you can be reasonably sure that the message is authentic.&lt;/p&gt;

&lt;h3 id="secret-key-encryption"&gt;Secret Key Encryption&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: Encryption without message authentication is vulnerable to chosen ciphertext attacks. Please read our whitepaper on &lt;a href="https://paragonie.com/white-paper/2015-secure-php-data-encryption#symmetric-encryption" rel="noopener noreferrer"&gt;Secure Data Encryption in PHP&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Formally, encryption is the reversible process of transforming of a message (called the &lt;code&gt;plaintext&lt;/code&gt;) and a &lt;strong&gt;secret key&lt;/strong&gt; into a seemingly random string of bytes (called the &lt;code&gt;ciphertext&lt;/code&gt;). i.e. &lt;code&gt;encrypt($message, $key)&lt;/code&gt; should return a unique string of random bytes for a given pair of &lt;code&gt;$message&lt;/code&gt; and &lt;code&gt;$key&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, &lt;a href="https://filippo.io/the-ecb-penguin" rel="noopener noreferrer"&gt;simple secret-key encryption (also known as ECB mode) is not secure&lt;/a&gt;. If you encrypt the same (16-byte, for the popular AES encryption algorithm) block within a message with the same key in ECB mode, the ciphertext will repeat.&lt;/p&gt;

&lt;p&gt;Modern secret-key encryption, therefore, actually accepts more than two pieces of information. Beyond the &lt;code&gt;plaintext&lt;/code&gt; message and a &lt;strong&gt;secret key&lt;/strong&gt;, they also require a unique &lt;em&gt;Initialization Vector&lt;/em&gt; (IV, for CBC mode) or &lt;em&gt;nonce&lt;/em&gt; (number to be used once, for CTR mode). &lt;a href="https://paragonie.com/white-paper/2015-secure-php-data-encryption#block-cipher-mode" rel="noopener noreferrer"&gt;The difference between a nonce and IV is subtle&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;None of the code on this page is secure; neither are any of the encryption keys.&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * This code is for example purposes only. DO NOT USE IT.
 * Use https://github.com/defuse/php-encryption instead
 * 
 * Demo: http://3v4l.org/ih8om
 */
bin2hex(
    openssl_encrypt(
      /* Message: */
        "The quick brown fox jumps over the lazy dog",
      /* Cipher algorithm and block mode: */
        'aes-128-ctr',
      /* Encryption key: (don't use weak keys like this ever, it's just an example!): */
        "\x01\x02\x03\x04" . "\x05\x06\x07\x08" . "\x09\x0a\x0b\x0c" . "\x0d\x0e\x0f\x10",
      /* Constant that means "don't encode": */
        OPENSSL_RAW_DATA,
      /* Initialization Vector or Nonce -- don't ever actually use all NULL bytes: */
        str_repeat("\0", 16) // This is a really bad way to generate a nonce or IV. 
    )
);
// 8f99e1315fcc7875325149dda085c504fc157e39c0b7f31c6c0b333136a7a8877c4971a5ce5688f94ae650

/**
 * This code is for example purposes only. DO NOT USE IT.
 * Use https://github.com/defuse/php-encryption instead
 * 
 * Demo: http://3v4l.org/ZgW38
 */
openssl_decrypt(
  /* Message: */
    hex2bin(
        "8f99e1315fcc7875325149dda085c504fc157e39c0b7f31c6c0b333136a7a8877c4971a5ce5688f94ae650"
    ),
  /* Cipher algorithm and block mode: */
    'aes-128-ctr',
  /* Encryption key: (don't use weak keys like this ever, it's just an example!): */
    "\x01\x02\x03\x04" . "\x05\x06\x07\x08" . "\x09\x0a\x0b\x0c" . "\x0d\x0e\x0f\x10",
  /* Constant that means "don't encode": */
    OPENSSL_RAW_DATA,
  /* Initialization Vector or Nonce -- don't ever actually use all NULL bytes: */
    str_repeat("\0", 16) // This is a really bad way to generate a nonce or IV.
);
// The quick brown fox jumps over the lazy dog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A more in-depth and less illustrative example (which properly generates IVs) is available &lt;a href="https://stackoverflow.com/a/30189841/2224584" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a closer examination at symmetric-key encryption with OpenSSL, read &lt;a href="https://paragonie.com/white-paper/2015-secure-php-data-encryption#symmetric-encryption" rel="noopener noreferrer"&gt;our white paper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Decryption is only successful if the same IV/nonce and secret key are used. However, only the key must be kept secret; the IV and nonce can even be broadcast with your encrypted message.&lt;/p&gt;

&lt;h3 id="authenticated-encryption"&gt;Authenticated Secret-Key Encryption
&lt;/h3&gt;

&lt;p&gt;If you recall from our earlier blog post, &lt;a href="https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly" rel="noopener noreferrer"&gt;&lt;em&gt;Using Encryption and Authentication Correctly&lt;/em&gt;&lt;/a&gt;, secret-key encryption itself is vulnerable to tampering unless you combine it with authentication.&lt;/p&gt;

&lt;p&gt;The only strategies proven to be secure are to &lt;a href="https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly#title.4.1" rel="noopener noreferrer"&gt;use an AEAD mode&lt;/a&gt; or to always &lt;strong&gt;encrypt first then authenticate the encrypted data&lt;/strong&gt; with a MAC.&lt;/p&gt;

&lt;p&gt;If you are following an Encrypt-Then-MAC construction, you want to use two separate secret keys: One for the encryption, the other for the MAC. In other words, apply the previous two sections together:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * This code is for example purposes only. DO NOT USE IT.
 * Use https://github.com/defuse/php-encryption instead
 */
$nonce = random_bytes(16);
$ciphertext = openssl_encrypt(
  /* Message: */
    "The quick brown fox jumps over the lazy dog",
  /* Cipher algorithm and block mode: */
    'aes-128-ctr',
  /* Encryption key: (don't use weak keys like this ever, it's just an example!)
   *    Instead, you want to generate 16, 24, or 32 random bytes (i.e. random_bytes(16))
   *    on your own. It's generally a bad idea to copy and paste security code.
   */
    "\x01\x02\x03\x04" . "\x05\x06\x07\x08" . "\x09\x0a\x0b\x0c" . "\x0d\x0e\x0f\x10",
  /* Constants that mean "don't encode" and "we have no padding" to the OpenSSL API: */
    OPENSSL_RAW_DATA + OPENSSL_ZERO_PADDING,
  /* Initialization Vector or Nonce: */
    $nonce
);
// You should choose a better HMAC key than we did for this article:
$mac = hash_hmac("sha256", $nonce.$ciphertext, "\xff\xfe\xfd\xfc" . "\xfb\xfa\xf9\xf8" . "\xf7\xf6\xf5\xf4" . "\xf3\xf2\xf1\xf0", true);
echo bin2hex($nonce.$ciphertext.$mac);
/*
   71b5546f 6cb857cd 0d8f8be3 f9312c74 &amp;lt;- Nonce (randomly chosen)
   356146df 274552c2 e98d3008 b1dfa35c &amp;lt;- Ciphertext
   60d6130d 9c9ca525 6c2f2f25 0b321176
   06563174 c3b073a0 5ab263
   4d1c7416 b086a316 a0474a05 84e3793c &amp;lt;- MAC
   a32fde09 0d82a5ef 213cb329 da3b5b06 
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It is important to exercise caution when combining cryptographic features. Our basic protocol as written above has no redundant features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secret key encryption provides &lt;strong&gt;confidentiality&lt;/strong&gt; such that it can only be read with the correct secret key. &lt;/li&gt;
&lt;li&gt;Keyed hash functions provide &lt;strong&gt;authentication&lt;/strong&gt; (and consequently, &lt;em&gt;message integrity&lt;/em&gt;) such that anyone possessing the correct secret key can recalculate the same MAC.&lt;/li&gt;
&lt;li&gt;A random IV/nonce is used to make each encrypted message unique, &lt;em&gt;even if the unencrypted message is the same&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should go without saying, but double-encrypting or double-authenticating when you need authenticated encryption would just be silly.&lt;/p&gt;

&lt;h2 id="public-key"&gt;Public Key Cryptography&lt;/h2&gt;

&lt;p&gt;Public key cryptography is challenging for nontechnical people to understand, and even more challenging for technical people to explain correctly without burying the reader in mathematics or missing critical points. The end result is usually a lot of confusion and occasionally a false sense of understanding. (A fauxreka moment, if you will.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fparagonie.com%2Ffiles%2Fblog%2Fcrypto_types.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fparagonie.com%2Ffiles%2Fblog%2Fcrypto_types.png" title="Secret Key Cryptography vs Public Key Cryptography" alt="Secret Key Cryptography vs Public Key Cryptography" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's all you need to know right now: Unlike secret key encryption, which involves a single secret key that is held by both parties, in public key cryptography, each participant has &lt;strong&gt;two keys&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each participant has a &lt;strong&gt;private key&lt;/strong&gt;, which they never share.&lt;/li&gt;
&lt;li&gt;Each participant also has a &lt;strong&gt;public key&lt;/strong&gt;, which is mathematically related to their private key, which they share with everyone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is unfortunate that the "key" terminology from secret key cryptography stuck when public key cryptography was discovered, as there aren't very many physical systems that are intuitively similar to what's going on here. Some people have attempted to &lt;a href="https://www.youtube.com/watch?v=3QnD2c4Xovk" rel="noopener noreferrer"&gt;explain public key cryptography using colors&lt;/a&gt; or &lt;a href="http://crypto.stackexchange.com/q/292/24405" rel="noopener noreferrer"&gt;detailed explanations&lt;/a&gt;. If you're interested in the intimate details, we recommend both of the links in the previous sentence.&lt;/p&gt;

&lt;p&gt;For everyone else, if you can accept these premises, understanding the rest isn't hard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To use public key cryptography, you generate a key-pair and share the public key, but keep the private key to yourself. (In most cases, every participant does this.)&lt;/li&gt;
&lt;li&gt;There is only one private key for any given public key.&lt;/li&gt;
&lt;li&gt;Both of the keys in a given key-pair are related to each other, mathematically.&lt;/li&gt;
&lt;li&gt;Given a public key, it is almost impossible to figure out what the private key is.&lt;/li&gt;
&lt;li&gt;Given a private key, you can near-instantly calculate the related public key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Got it? Let's build something with this understanding.&lt;/p&gt;

&lt;h3 id="diffie-hellman"&gt;Shared Secret Key Agreement&lt;/h3&gt;

&lt;p&gt;Let's say you want to talk to a friend over the Internet using secret key cryptography (which is much faster than public key cryptography), but you don't want anyone else to read it. You and her haven't already agreed upon a secret key. How do you do it?&lt;/p&gt;

&lt;p&gt;Glossing over the finer details (the color video above explains it fairly well), this is what you do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You send her your public key (yellow).&lt;/li&gt;
&lt;li&gt;She sends you her public key (light blue).&lt;/li&gt;
&lt;li&gt;Combine your private key (green) and her public key (blue) to form a shared secret key.&lt;/li&gt;
&lt;li&gt;She will combine her private key (red) with your public key (yellow) to form &lt;strong&gt;the same exact shared key&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How? &lt;a href="https://www.khanacademy.org/computing/computer-science/cryptography/modern-crypt/v/diffie-hellman-key-exchange-part-2" rel="noopener noreferrer"&gt;Modular arithmetic&lt;/a&gt; (classic Diffie Hellman) or &lt;a href="https://www.youtube.com/watch?v=l6jTFxQaUJA" rel="noopener noreferrer"&gt;multiplication along elliptic curves over finite fields&lt;/a&gt; (modern Elliptic Curve Diffie Hellman).&lt;/p&gt;

&lt;h3 id="digital-signatures"&gt;Digital Signatures&lt;/h3&gt;

&lt;p&gt;Digital signature algorithms, such as &lt;a href="https://en.wikipedia.org/wiki/EdDSA" rel="noopener noreferrer"&gt;EdDSA&lt;/a&gt; (Edwards-curve Digital Signature Algorithm), are one of the most useful innovations to result from public key cryptography.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;digital signature&lt;/strong&gt; is calculated from a &lt;strong&gt;message&lt;/strong&gt; and a &lt;strong&gt;private key&lt;/strong&gt;. Earlier algorithms (such as ECDSA) also required you to generate a unique random nonce for each message, but this was proven to be &lt;a href="http://psx-scene.com/forums/content/sony-s-ps3-security-epic-fail-videos-within-581/" rel="noopener noreferrer"&gt;error-prone&lt;/a&gt; in the real world.&lt;/p&gt;

&lt;p&gt;Anyone else with a copy of your &lt;strong&gt;public key&lt;/strong&gt; can verify that a particular message was signed by your private key. Unlike keyed hash functions, this verification takes place without requiring you to reveal your private key. &lt;/p&gt;

&lt;h1&gt;
  
  
  Common Misconceptions and Pitfalls
&lt;/h1&gt;

&lt;h2 id="passwords"&gt;Password Storage&lt;/h2&gt;

&lt;p&gt;Quick answer: &lt;a href="https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016" rel="noopener noreferrer"&gt;Just use bcrypt&lt;/a&gt;. For PHP developers, this means &lt;a href="https://secure.php.net/password_hash" rel="noopener noreferrer"&gt;&lt;code&gt;password_hash()&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://secure.php.net/password_hash" rel="noopener noreferrer"&gt;&lt;code&gt;password_verify()&lt;/code&gt;&lt;/a&gt; rather than &lt;code&gt;crypt()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Many developers think passwords should be &lt;em&gt;encrypted&lt;/em&gt;, but this is false. &lt;strong&gt;Passwords should be *hashed&lt;/strong&gt;*, not encrypted. Furthermore, don't confuse password hashing algorithms with simple cryptographic hash functions. They're not the same thing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Cryptographic Hashes&lt;/th&gt;
&lt;th&gt;Password Hashes&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;
&lt;ul&gt;
&lt;li&gt;Fast&lt;/li&gt;
&lt;li&gt;Only one input: The message&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;Intentionally slow&lt;/li&gt;
&lt;li&gt;At least three inputs:&lt;ol&gt;
&lt;li&gt;The password&lt;/li&gt;
&lt;li&gt;A per-user salt&lt;/li&gt;
&lt;li&gt;A cost factor (how expensive to make the computation)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Unlike cryptographic hashes, password hashes require more than one input parameter. But unlike encryption algorithms, password hashes are one-way deterministic trap door calculations. Also unlike secret-key encryption, the salt does not need to remain secret; it merely needs to be unique per user. The purpose of a unique salt per user is to thwart pre-computation and to make brute-force guessing passwords from a list of hashes more expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I encrypt my (bcrypt) password hashes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. If you run your web application and your database on separate hardware servers, this actually provides a substantial defense in depth. That's the reasoning behind our &lt;a href="https://github.com/paragonie/password_lock" rel="noopener noreferrer"&gt;password_lock&lt;/a&gt; library.&lt;/p&gt;

&lt;h2 id="download-verification"&gt;File Verification&lt;/h2&gt;

&lt;p&gt;Digital signatures can prove authenticity, cryptographic hash functions can not.&lt;/p&gt;

&lt;p&gt;There is a nontrivial portion of technical users that will, upon downloading an executable from a website, recalculate the MD5 or SHA1 hash of the file and compare it to one displayed on the web page they downloaded the file from. If it matches, they will execute the file, fully trusting its contents to be genuine. &lt;/p&gt;

&lt;p&gt;If both the file and the hash value are stored on the same server, this is a completely ludicrous waste of time: &lt;strong&gt;Any attacker who can alter your download can replace the hashes on the web page too.&lt;/strong&gt; (If the file and hash are on separate servers, the situation is a little different, but the improvement is not significant enough to warrant eschewing a better solution.)&lt;/p&gt;

&lt;p&gt;After all, as we said above, hash functions like MD5 and SHA1 produce a deterministic fixed-size output for a given input. There are no secrets involved. When a solution does not increase security but makes people feel more secure, we call them &lt;a href="https://en.wikipedia.org/wiki/Security_theater" rel="noopener noreferrer"&gt;security theater&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cryptographic hash functions are security theater in this situation. You want &lt;strong&gt;digital signatures&lt;/strong&gt; instead.&lt;/p&gt;

&lt;p&gt;To improve security, instead of posting MD5/SHA1 hashes, the software vendor can instead sign their package with their EdDSA private key and share their EdDSA public key far and wide. When you download the file, you should also download the signature and, using the verified public key, check that it is authentic.&lt;/p&gt;

&lt;p&gt;For example: &lt;a href="https://github.com/jedisct1/minisign" rel="noopener noreferrer"&gt;Minisign&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A keyed hash function won't work here either, as you would need to distribute the secret key in order for anyone to be able to verify the signature. If they have the secret key, they can forge their own signatures for maliciously altered message (in this case, executable file).&lt;/p&gt;

&lt;p&gt;Digital signatures are the best way to achieve assurance about the authenticity of a download. MD5/SHA1 hashes are almost always useless here.&lt;/p&gt;

&lt;h2 id="encoding-compression"&gt;Encoding and Compression Aren't Cryptographic
&lt;/h2&gt;

&lt;p&gt;A common beginner's mistake is to use an encoding function, such as &lt;code&gt;base64_encode()&lt;/code&gt;, to attempt to obfuscate information. Consider the following code, which was offered in a LinkedIn discussion about how to properly store passwords in a PHP web application:&lt;/p&gt;

&lt;blockquote&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fparagonie.com%2Ffiles%2Fblog%2Fbase64_password.png" alt="The worst password 'hashing' function of all time." title="The worst password 'hashing' function of all time." width="" height=""&gt;&lt;br&gt;This may very well be &lt;a href="http://3v4l.org/BZ7rC" rel="noopener noreferrer"&gt;the worst password storage function ever written&lt;/a&gt;.&lt;/blockquote&gt;

&lt;p&gt;A lot of developers will either encode or compress information and assume their solution provides the same level of security as actual cryptographic features simply because the output is not human readable. It doesn't.&lt;/p&gt;

&lt;p&gt;Encoding and compression algorithms are both &lt;strong&gt;reversible, keyless transformations of information&lt;/strong&gt;. Encoding specifies how information should be represented in human-readable text. Compression attempts to reduce an input to as little space as possible. Both are useful, but they are not cryptographic features.&lt;/p&gt;

&lt;h1 id="recap"&gt;Recap&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cryptographic hash algorithms&lt;/strong&gt; (e.g. SHA256) are deterministic one-way algorithms that require &lt;code&gt;zero&lt;/code&gt; keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyed hashing algorithms&lt;/strong&gt; (e.g. HMAC) are used for authentication in secret-key cryptography; requires &lt;code&gt;one&lt;/code&gt; key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret-key encryption algorithms&lt;/strong&gt; (e.g. AES-CTR) are used to transform messages so only someone possessing the secret key can reverse; requires one &lt;code&gt;key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared secret agreement algorithms&lt;/strong&gt; (e.g. ECDH) are used to negotiate a shared secret key while only requiring the public transmission of both party's public keys. Requires &lt;code&gt;four&lt;/code&gt; keys (two pairs of private/public) to generate a fifth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Digital signature algorithms&lt;/strong&gt; (e.g. Ed25519) are used to sign messages (with one's private key) that anyone possessing the corresponding public key can validate. Requires &lt;code&gt;two&lt;/code&gt; keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password hashing algorithms&lt;/strong&gt; (e.g. bcrypt) are slow hashing algorithms designed specifically for being difficult to efficiently attack with a brute force search. Requires &lt;code&gt;one&lt;/code&gt; secret input and a per-user salt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encoding algorithms&lt;/strong&gt; (e.g. Base64) are not cryptographic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression algorithms&lt;/strong&gt; (e.g. gzip) are not cryptographic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keep in Mind
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't encrypt passwords.&lt;/strong&gt; Instead, hash them with a password hashing algorithm. (You may encrypt the hashes.) Hash functions like MD5, SHA1, and SHA256 are not encryption. Anyone who uses the phrase "password encryption" probably needs to read this entire page carefully, because they are deeply mistaken.&lt;/li&gt;
&lt;li&gt;Secret-key &lt;a href="https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly" rel="noopener noreferrer"&gt;encryption without message authentication&lt;/a&gt; is insecure (it's vulnerable to chosen ciphertext attacks).&lt;/li&gt;
&lt;li&gt;For downloads: digital signatures prove authenticity, hashes do not. You want a Minsign or GPG signature, not an MD5 hash.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We hope that this post serves as a good introduction to cryptography concepts. Our team publishes new posts about cryptography, application security, and web development in PHP anywhere from 2 to 5 times per month (usually on Friday). We also offer &lt;a href="https://paragonie.com/service/code-review" rel="noopener noreferrer"&gt;code review&lt;/a&gt; and &lt;a href="https://paragonie.com/service/technology-consulting" rel="noopener noreferrer"&gt;technology consulting&lt;/a&gt; services.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
