js-nacl
Version:
Emscripten-compiled Javascript version of NaCl, the Networking and Cryptography library.
333 lines (223 loc) • 13.4 kB
HTML
<h1>js-nacl: Pure-Javascript Emscripten-compiled NaCl routines</h1>
<p><a href="https://github.com/kripken/emscripten">Emscripten</a>-compiled
<a href="http://nacl.cr.yp.to/">NaCl</a>, a cryptographic library. Includes both
in-browser and node.js support.</p>
<p>The paper "<a href="http://cr.yp.to/highspeed/coolnacl-20120725.pdf">The security impact of a new cryptographic
library</a>" is an
excellent summary of the motivation behind the NaCl API and library
design.</p>
<p>Using this library in the browser requires support for the newish
<code>window.crypto.getRandomValues</code> API.</p>
<h2>NPM Package</h2>
<p>This library is <a href="https://npmjs.org/package/js-nacl">registered on
npmjs.org</a>. To install it:</p>
<pre><code>npm install js-nacl
</code></pre>
<h2>Building the library</h2>
<p>The git checkout includes a pre-compiled version of the library, so
you won't need Emscripten unless you want to change something about
the underlying NaCl library itself.</p>
<p>Essentially, the source checkout contains everything you will need to
use the library in both the browser and in node.js.</p>
<p>If you do find yourself wanting to build the library, see the
instructions in
<a href="https://github.com/tonyg/js-nacl/blob/master/BUILDING.md">BUILDING.md</a>.</p>
<h2>Using the library</h2>
<p>In the browser, include the <code>lib/nacl.js</code> script:</p>
<pre><code><script src="lib/nacl.js"></script>
...
<script> alert(nacl.to_hex(nacl.random_bytes(16))); </script>
</code></pre>
<p>In node.js, require the <code>lib/nacl.js</code> module:</p>
<pre><code>var nacl = require("./lib/nacl.js");
...
console.log(nacl.to_hex(nacl.random_bytes(16)));
</code></pre>
<p>Or if you have installed the library via <code>npm</code>,</p>
<pre><code>var nacl = require("js-nacl");
...
console.log(nacl.to_hex(nacl.random_bytes(16)));
</code></pre>
<h2>Strings vs. Binary Data</h2>
<p>The library enforces a strict distinction between strings and binary
data. Binary data is represented using instances of
<a href="https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays/Uint8Array"><code>Uint8Array</code></a>.</p>
<h3>nacl.to_hex(Uint8Array) → String</h3>
<p>Returns a lower-case hexadecimal representation of the given binary
data.</p>
<h3>nacl.encode_utf8(String) → Uint8Array</h3>
<p>Returns the binary equivalent of the argument, encoded using UTF-8.</p>
<h3>nacl.encode_latin1(String) → Uint8Array</h3>
<p>Returns the binary equivalent of the argument, encoded using Latin1
(an 8-bit clean encoding). If any of the character codes in the
argument string are greater than 255, an exception is thrown.</p>
<h3>nacl.decode_utf8(Uint8Array) → String</h3>
<p>Decodes the binary data in the argument using the UTF-8 encoding,
producing the corresponding string.</p>
<h3>nacl.decode_latin1(Uint8Array) → String</h3>
<p>Decodes the binary data in the argument using the Latin1 8-bit clean
encoding, producing the corresponding string.</p>
<h2>Hashing: crypto_hash</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/hash.html">NaCl crypto_hash API</a>.</p>
<h3>nacl.crypto_hash(Uint8Array) → Uint8Array</h3>
<p>Computes the SHA-512 hash of its argument.</p>
<p>While SHA-512 is recommended, the SHA-256 function is also available,
as <code>nacl.crypto\_hash\_sha256</code>.</p>
<h3>nacl.crypto_hash_string(String) → Uint8Array</h3>
<p>Encodes its argument using <code>nacl.encode_utf8</code>, and then calls
<code>crypto_hash</code>.</p>
<h2>Public-key authenticated encryption: crypto_box</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/box.html">NaCl crypto_box API</a>.</p>
<p><strong>Make sure to follow the instructions regarding nonce selection given
in the "Security model" section of the NaCl API documentation!</strong></p>
<pre><code>senderKeypair = nacl.crypto_box_keypair();
recipientKeypair = nacl.crypto_box_keypair();
message = nacl.encode_utf8("Hello!");
nonce = nacl.crypto_box_random_nonce();
packet = nacl.crypto_box(message, nonce, recipientKeypair.boxPk, senderKeypair.boxSk);
decoded = nacl.crypto_box_open(packet, nonce, senderKeypair.boxPk, recipientKeypair.boxSk);
"Hello!" === nacl.decode_utf8(decoded); // always true
</code></pre>
<h3>nacl.crypto_box_keypair() → {"boxPk": Uint8Array, "boxSk": Uint8Array}</h3>
<p>Creates a fresh random keypair. <code>boxPk</code> is the public key and <code>boxSk</code>
is the secret key.</p>
<h3>nacl.crypto_box_random_nonce() → Uint8Array</h3>
<p>Returns a fresh randomly-chosen nonce suitable for use with
<code>crypto_box</code>.</p>
<h3>nacl.crypto_box(msgBin, nonceBin, recipientPublicKeyBin, senderSecretKeyBin) → Uint8Array</h3>
<p>Places <code>msg</code> in an authenticated, encrypted box that can only be
verified and decrypted by the secret key corresponding to
<code>recipientPublicKey</code>.</p>
<h3>nacl.crypto_box_open(ciphertextBin, nonceBin, senderPublicKeyBin, recipientSecretKeyBin) → Uint8Array</h3>
<p>Verifies and decrypts a box from <code>crypto_box</code>. Throws an exception if
the verification fails or any of the inputs are invalid.</p>
<h3>nacl.crypto_box_precompute(publicKeyBin, secretKeyBin) → {"boxK": Uint8Array}</h3>
<p>Precomputes a shared secret between two parties. See the documentation
for <code>crypto_box_beforenm</code> at the NaCl website.</p>
<h3>nacl.crypto_box_precomputed(msgBin, nonceBin, {"boxK": Uint8Array}) → Uint8Array<br>nacl.crypto_box_open_precomputed(ciphertextBin, nonceBin, {"boxK": Uint8Array}) → Uint8Array</h3>
<p>Precomputed-secret variants of <code>crypto_box</code> and <code>crypto_box_open</code>.</p>
<h2>Secret-key authenticated encryption: crypto_secretbox</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/secretbox.html">NaCl crypto_secretbox API</a>.</p>
<p><strong>Make sure to follow the instructions regarding nonce selection given
in the "Security model" section of the NaCl API documentation!</strong></p>
<pre><code>k = ...;
m = nacl.encode_utf8("message");
n = nacl.crypto_secretbox_random_nonce();
c = nacl.crypto_secretbox(m, n, k);
m1 = nacl.crypto_secretbox_open(c, n, k);
"message" === nacl.decode_utf8(m1); // always true
</code></pre>
<h3>nacl.crypto_secretbox_random_nonce() → Uint8Array</h3>
<p>Returns a fresh randomly-chosen nonce suitable for use with
<code>crypto_secretbox</code>.</p>
<h3>nacl.crypto_secretbox(msgBin, nonceBin, keyBin) → Uint8Array</h3>
<p>Places <code>msg</code> in an authenticated, encrypted box that can only be
verified and decrypted by someone who knows <code>keyBin</code>. The <code>keyBin</code>
Uint8Array must be <code>nacl.crypto_secretbox_KEYBYTES</code> bytes long.</p>
<h3>nacl.crypto_secretbox_open(ciphertextBin, nonceBin, keyBin) → Uint8Array</h3>
<p>Verifies and decrypts a packet from <code>crypto_secretbox</code>. Throws an
exception if the verification fails or any of the inputs are invalid.</p>
<h2>Secret-key encryption: crypto_stream</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/stream.html">NaCl crypto_stream API</a>.</p>
<p><strong>Make sure to follow the instructions regarding nonce selection given
in the "Security model" section of the NaCl API documentation!</strong></p>
<p>Since this style of secret-key encryption is symmetric,
<code>nacl.crypto_stream_xor</code> is suitable for decryption as well as
encryption:</p>
<pre><code>k = ...;
m = nacl.encode_utf8("message");
n = nacl.crypto_stream_random_nonce();
c = nacl.crypto_stream_xor(m, n, k);
m1 = nacl.crypto_stream_xor(c, n, k);
"message" === nacl.decode_utf8(m1); // always true
</code></pre>
<h3>nacl.crypto_stream_random_nonce() → Uint8Array</h3>
<p>Returns a fresh randomly-chosen nonce suitable for use with
<code>crypto_stream</code>.</p>
<h3>nacl.crypto_stream(lenInt, nonceBin, keyBin) → Uint8Array</h3>
<p>Returns a <code>lenInt</code>-byte length keystream based on the given nonce and
key. The key must be <code>nacl.crypto_stream_KEYBYTES</code> bytes long.</p>
<h3>nacl.crypto_stream_xor(msgBin, nonceBin, keyBin) → Uint8Array</h3>
<p>Returns <code>msgBin.length</code> bytes of ciphertext (or plaintext, depending
on the contents of <code>msgBin</code>) produced by XORing <code>msgBin</code> with the
result of <code>nacl.crypto_stream(msgBin.length, nonceBin, keyBin)</code>.</p>
<h2>Secret-key single-message authentication: crypto_onetimeauth</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/onetimeauth.html">NaCl crypto_onetimeauth API</a>.</p>
<h2>Secret-key message authentication: crypto_auth</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/auth.html">NaCl crypto_auth API</a>.</p>
<h2>Signatures: crypto_sign</h2>
<p>Follows the <a href="http://nacl.cr.yp.to/sign.html">NaCl crypto_sign API</a>.</p>
<p>Note the warning in the NaCl API documentation:</p>
<blockquote>
<p>WARNING: This signature software (both at the C level and at the C++
level) is a prototype. It will be replaced by the final system
<a href="http://ed25519.cr.yp.to/">Ed25519</a> in future NaCl releases. A
NaCl-compatible Ed25519 implementation is already available as part
of <a href="http://bench.cr.yp.to/supercop.html">SUPERCOP</a>.</p>
</blockquote>
<h3>nacl.crypto_sign_keypair() → {"signPk": Uint8Array, "signSk": Uint8Array}</h3>
<p>Creates a fresh random keypair. <code>signPk</code> is the public key and
<code>signSk</code> is the secret key.</p>
<pre><code>k = nacl.crypto_sign_keypair();
m = nacl.encode_utf8("message");
signed_m = nacl.crypto_sign(m, k.signSk);
m1 = nacl.crypto_sign_open(signed_m, k.signPk);
"message" === nacl.decode_utf8(m1); // always true
</code></pre>
<h3>nacl.crypto_sign(msgBin, signerSecretKey) → Uint8Array</h3>
<p>Produces a signature-wrapped version of <code>msgBin</code>.</p>
<h3>nacl.crypto_sign_open(packetBin, signerPublicKey) → (Uint8Array || null)</h3>
<p>Verifies the signature on the given <code>packetBin</code>, and if it is valid,
extracts the carried message and returns it. If the signature could
not be verified, returns <code>null</code>.</p>
<h2>Derived Keys</h2>
<p><strong>WARNING: Experimental</strong></p>
<p>If you see yourself wanting to use these, you will need to know why
<a href="http://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a> and
<a href="http://www.tarsnap.com/scrypt.html">scrypt</a> are of crucial
importance.</p>
<p>You might like to explore the use of these functions in tandem with
<code>scrypt.crypto_scrypt</code> from
<a href="https://github.com/tonyg/js-scrypt">js-scrypt</a>.</p>
<h3>nacl.crypto_sign_keypair_from_seed(Uint8Array) → {"signPk": Uint8Array, "signSk": Uint8Array}</h3>
<p>Produces a <em>signing</em> keypair from its argument. A given binary input
will always produce the same keypair as output.</p>
<p>Compatible with <a href="https://github.com/warner/pynacl">PyNaCl</a>'s
<code>crypto_sign_keypair_fromseed</code> and
<a href="https://github.com/tonyg/racl">racl</a>'s <code>bytes->crypto-sign-keypair</code>.</p>
<h3>nacl.crypto_box_keypair_from_seed(Uint8Array) → {"boxPk": Uint8Array, "boxSk": Uint8Array}</h3>
<p>Produces an <em>encrypted authenticated box</em> keypair from its argument. A
given binary input will always produce the same keypair as output.</p>
<p>Compatible with <a href="https://github.com/tonyg/racl">racl</a>'s
<code>bytes->crypto-box-keypair</code>.</p>
<h2>License</h2>
<p>js-nacl is written by Tony Garnock-Jones <a href="mailto:tonygarnockjones@gmail.com">tonygarnockjones@gmail.com</a>
and is licensed under the <a href="http://opensource.org/licenses/MIT">MIT
license</a>:</p>
<blockquote>
<p>Copyright © 2013 Tony Garnock-Jones.</p>
<p>Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:</p>
<p>The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</p>
</blockquote>
<p>js-nacl relies on NaCl itself, which is public domain code by Daniel
J. Bernstein and others.</p>
<p>js-nacl's build process relies on (a modified version of) the
<code>import.py</code> script by Brian Warner, which comes from
<a href="https://github.com/warner/pynacl">PyNaCl</a> and is licensed under
<a href="http://www.apache.org/licenses/LICENSE-2.0.html">version 2.0 of the Apache
license</a>.</p>