epubjs
Version:
Render ePub documents in the browser, across many devices
497 lines (482 loc) • 118 kB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Chapter 5. Helper APIs</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="chapter" title="Chapter 5. Helper APIs"><div class="titlepage"><div><div><h1 class="title"><a id="chapter_7"/>Chapter 5. Helper APIs</h1></div></div></div><p><a id="chap7_id35950533"/>This chapter covers a number of <a id="ap5.0" class="indexterm"/>APIs that you’ll almost certainly use regularly but aren’t
used as much as those discussed in <a class="xref" href="ch04.html" title="Chapter 4. Core APIs">Chapter 4</a>.</p><div class="sect1" title="DNS"><div class="titlepage"><div><div><h1 class="title"><a id="chap7_id35959611"/>DNS</h1></div></div></div><p><a id="chap7_id35959699"/>Programmers, like end users, normally want to
refer to things by their domain names instead of their IP addresses. The
DNS module provides this lookup facility to you, but it is also used under
the hood whenever you are able to use a domain name—for example, in
<code class="literal">HTTP</code> clients.</p><p><a id="chap7_id35959707"/>The <code class="literal">dns</code>
module <a id="I_indexterm2_d1e6274" class="indexterm"/>consists of two main methods and a number of convenience
methods. The two main methods are <code class="literal">resolve()</code>, which turns a domain name into a DNS
record, and <code class="literal">reverse()</code>, which <a id="I_indexterm2_d1e6286" class="indexterm"/>turns an IP address into a domain. All of the other methods
in the <code class="literal">dns</code> module are more specialized
forms of these methods.</p><p><a id="chap7_id35951636"/><code class="literal">dns.resolve()</code> takes <a id="dn5.1" class="indexterm"/>three arguments:</p><div class="variablelist"><dl><dt><span class="term">A string containing the domain to be resolved</span></dt><dd><p><a id="chap7_id35951649"/><a id="chap7_id35951651"/>This can include subdomains, such as
<code class="literal">www.yahoo.com</code>. The <code class="literal">www</code> is technically a hostname, but the
system will resolve it for you.</p></dd><dt><span class="term">A string containing the types of records being requested</span></dt><dd><p><a id="chap7_id35951669"/><a id="chap7_id35951671"/>This requires a little more
understanding of DNS. Most people are familiar with the “address” or
A record type. This type of record maps an IPv4 domain to a domain
name (as defined in the previous item). The “canonical name,” or
<a id="I_indexterm2_d1e6325" class="indexterm"/><a id="I_indexterm2_d1e6328" class="indexterm"/>CNAME, records allow you to create an alias of an A
<a id="I_indexterm2_d1e6332" class="indexterm"/><a id="I_indexterm2_d1e6335" class="indexterm"/>record or another CNAME. For example, <code class="literal">www.example.com</code> might be a CNAME of the A
record at <code class="literal">example.com</code>. MX records
<a id="I_indexterm2_d1e6346" class="indexterm"/><a id="I_indexterm2_d1e6349" class="indexterm"/>point to the mail server for a domain for the use of
SMTP. When you email <code class="literal">person@domain.com</code>, the MX record for
<code class="literal">domain.com</code> tells your email
server where to send their mail. Text records, or <a id="I_indexterm2_d1e6359" class="indexterm"/><a id="I_indexterm2_d1e6362" class="indexterm"/>TXT, are notes attached to a domain. They have been
used for all kinds of functions. The final type supported by this
library is service, or SRV, <a id="I_indexterm2_d1e6366" class="indexterm"/><a id="I_indexterm2_d1e6370" class="indexterm"/>records, which provide information on the services
available at a particular domain.</p></dd><dt><span class="term">A callback</span></dt><dd><p><a id="chap7_id35951700"/><a id="chap7_id35951702"/>This returns the <a id="I_indexterm2_d1e6380" class="indexterm"/>response from the DNS server. The prototype will be
shown in <a class="xref" href="ch05.html#chap7_id35959800" title="Example 5-2. Using resolve( ) versus resolveMx( )">Example 5-2</a>.</p></dd></dl></div><p><a id="chap7_id35959749"/>As shown in <a class="xref" href="ch05.html#chap7_id35959755" title="Example 5-1. Calling dns.resolve( )">Example 5-1</a>, calling <code class="literal">dns.resolve()</code> is easy, although the callback may
be slightly different from other callbacks you’ve used so far.</p><div class="example"><a id="chap7_id35959755"/><p class="title">Example 5-1. Calling dns.resolve( )</p><div class="example-contents"><a id="chap7_id35959761"/><pre class="programlisting">dns.resolve('yahoo.com', 'A', function(e,r) {
if (e) {
console.log(e);
}
console.log(r);
} );</pre></div></div><p><a id="chap7_id35959771"/>We called <code class="literal">dns.resolve()</code> with the domain and a record type
of <code class="literal">A</code>, along with a trivial callback
that prints results. The first argument of the callback is an error
object. If an error occurs, the object will be non-null, and we can
consult it to see what went wrong. The second argument is a list of the
records returned by the query.</p><p><a id="chap7_id35951754"/>There are convenience methods for all the
types of records listed earlier. For example, rather than calling <code class="literal">resolve('example.com', 'MX',</code>
<code class="literal">callback</code><code class="literal">)</code>, you can
<a id="I_indexterm2_d1e6418" class="indexterm"/>call <code class="literal">resolveMx('example.com',
callback)</code> instead (see <a class="xref" href="ch05.html#chap7_id35959800" title="Example 5-2. Using resolve( ) versus resolveMx( )">Example 5-2</a>). The
API also <a id="I_indexterm2_d1e6430" class="indexterm"/><a id="I_indexterm2_d1e6435" class="indexterm"/>provides <code class="literal">resolve4()</code> and
<code class="literal">resolve6()</code> methods, which resolve
<a id="I_indexterm2_d1e6447" class="indexterm"/><a id="I_indexterm2_d1e6450" class="indexterm"/>IPv4 and IPv6 address records, respectively.</p><div class="example"><a id="chap7_id35959800"/><p class="title">Example 5-2. Using resolve( ) versus resolveMx( )</p><div class="example-contents"><a id="chap7_id35959805"/><pre class="programlisting">var dns = require('dns');
dns.resolve('example.com', 'MX', function(e, r) {
if (e) {
console.log(e);
}
console.log(r);
});
dns.resolveMx('example.com', function(e, r) {
if (e) {
console.log(e);
}
console.log(r);
});</pre></div></div><p><a id="chap7_id35959816"/>Because <code class="literal">resolve()</code> usually returns a list containing many
IP addresses, there is also a convenience method <a id="I_indexterm2_d1e6467" class="indexterm"/>called <code class="literal">dns.lookup()</code> that
returns just one IP address from an A record query (see <a class="xref" href="ch05.html#chap7_id35959828" title="Example 5-3. Looking up a single A record with lookup( )">Example 5-3</a>). The method takes a domain, an IP family
(<code class="literal">4</code> or <code class="literal">6</code>), and a callback. However,
unlike <code class="literal">.dns.resolve()</code>, it always
returns a single address. If you don’t pass an address, it defaults to the
network interface’s current <a id="I_indexterm2_d1e6488" class="indexterm"/>setting.</p><div class="example"><a id="chap7_id35959828"/><p class="title">Example 5-3. Looking up a single A record with lookup( )</p><div class="example-contents"><a id="chap7_id35959834"/><pre class="programlisting">var dns = require('dns');
dns.lookup('google.com', 4, function(e, a) {
console.log(a);
});</pre></div></div></div><div class="sect1" title="Crypto"><div class="titlepage"><div><div><h1 class="title"><a id="chap7_id35951837"/>Crypto</h1></div></div></div><p><a id="chap7_id35951842"/>Cryptography is <a id="I_indexterm2_d1e6502" class="indexterm"/>used in lots of places for a variety of tasks. Node uses the
OpenSSL library <a id="I_indexterm2_d1e6508" class="indexterm"/>as the basis of its cryptography. This is because OpenSSL is
already a well-tested, hardened implementation of cryptographic
algorithms. But you have to compile Node with OpenSSL support in order to
use the methods in this section.</p><p><a id="chap7_id35951852"/>The <a id="I_indexterm2_d1e6516" class="indexterm"/>cryptograph module enables a number of different tasks.
First, it powers the SSL/TLS parts of Node. Second, it contains <a id="ha5.2" class="indexterm"/><a id="I_indexterm2_d1e6527" class="indexterm"/><a id="I_indexterm2_d1e6530" class="indexterm"/>hashing algorithms such as MD5 or SHA-1 that you might want
to use in your application. Third, it allows you to use <a id="I_indexterm2_d1e6534" class="indexterm"/><a id="I_indexterm2_d1e6539" class="indexterm"/><a id="I_indexterm2_d1e6542" class="indexterm"/><a id="cr5.2" class="indexterm"/><a id="I_indexterm2_d1e6551" class="indexterm"/>HMAC.<sup>[<a id="id833182" href="#ftn.id833182" class="footnote">12</a>]</sup> There are some encryption methods to cipher the data with to
ensure it is encrypted. Finally, HMAC contains other public key
cryptographic functions to sign data and verify signatures.</p><p><a id="chap7_id35951868"/>Each of the functions that cryptography does
is contained within a class (or classes), which we’ll look at in the
following sections.</p><div class="sect2" title="Hashing"><div class="titlepage"><div><div><h2 class="title"><a id="chap7_id35951872"/>Hashing</h2></div></div></div><p><a id="chap7_id35951878"/>Hashes are used for a few <a id="I_indexterm2_d1e6571" class="indexterm"/>important functions, such as obfuscating data in a way
that allows it to be validated or providing a small checksum for a much
larger piece of data. To use hashes in Node, you should create a
<code class="literal">Hash</code> object using the factory method
<code class="literal">crypto.createHash()</code>. This <a id="I_indexterm2_d1e6583" class="indexterm"/>returns a new <code class="literal">Hash</code>
instance using a specified hashing algorithm. Most popular algorithms
are available. The exact ones depend on your version of OpenSSL, but
common ones <a id="I_indexterm2_d1e6593" class="indexterm"/><a id="I_indexterm2_d1e6596" class="indexterm"/><a id="I_indexterm2_d1e6599" class="indexterm"/>are:</p><div class="itemizedlist"><a id="chap7_id35951894"/><ul class="itemizedlist"><li class="listitem"><p><a id="chap7_id35951896"/><a id="chap7_id35951897"/><code class="literal">md5</code></p></li><li class="listitem"><p><a id="chap7_id35951900"/><a id="chap7_id35951901"/><code class="literal">sha1</code></p></li><li class="listitem"><p><a id="chap7_id35951905"/><a id="chap7_id35951906"/><code class="literal">sha256</code></p></li><li class="listitem"><p><a id="chap7_id35951909"/><a id="chap7_id35951910"/><code class="literal">sha512</code></p></li><li class="listitem"><p><a id="chap7_id35951913"/><a id="chap7_id35951914"/><code class="literal">ripemd160</code></p></li></ul></div><p><a id="chap7_id35951918"/>These algorithms all have different
advantages and disadvantages. MD5, for example, is used in many
applications but has a number of known flaws, including collision
issues.<sup>[<a id="id833335" href="#ftn.id833335" class="footnote">13</a>]</sup> Depending on your application, you can pick either a
widely deployed algorithm such as MD5 or (preferably) the newer
<a id="I_indexterm2_d1e6630" class="indexterm"/><a id="I_indexterm2_d1e6633" class="indexterm"/>SHA1, or a less universal but more hardened algorithm such
as RIPEMD, SHA256, or SHA512.</p><p><a id="chap7_id35951931"/>Once you have data in the hash, you can use
it to create a digest by <a id="crh5.2.1" class="indexterm"/><a id="hcd5.2.1" class="indexterm"/>calling <code class="literal"><em class="replaceable"><code>hash</code></em>.update()</code> with
the hash data (<a class="xref" href="ch05.html#chap7_id35951957" title="Example 5-4. Creating a digest using Hash">Example 5-4</a>). You can keep
updating a <code class="literal">Hash</code> with more data until
you want to output it; the data you add to the hash is simply
concatenated to the data passed in previous calls. To output the hash,
call the <code class="literal"><em class="replaceable"><code>hash</code></em>.digest()</code>
method. This will output the digest of the data that was input into the
hash <a id="hcu5.2.1" class="indexterm"/>with <code class="literal"><em class="replaceable"><code>hash</code></em>.update()</code>. No
more data can be added after you call <code class="literal"><em class="replaceable"><code>hash</code></em>.digest()</code>.</p><div class="example"><a id="chap7_id35951957"/><p class="title">Example 5-4. Creating a digest using Hash</p><div class="example-contents"><a id="chap7_id35951964"/><pre class="programlisting">> var crypto = require('crypto');
> var md5 = crypto.createHash('md5');
> md5.update('foo');
{}
> md5.digest();
'¬½\u0018ÛLÂø\\íïeOÌĤØ'
></pre></div></div><p><a id="chap7_id35951977"/>Notice that the output of the digest is a
bit weird. That’s because it’s the binary representation. More commonly,
a digest is printed in hex. We can do that by adding <code class="literal">'hex'</code> as a parameter to <code class="literal"><em class="replaceable"><code>hash</code></em>.digest</code>, as in
<a class="xref" href="ch05.html#chap7_id35951988" title="Example 5-5. The lifespan of hashes and getting hex output">Example 5-5</a>.</p><div class="example"><a id="chap7_id35951988"/><p class="title">Example 5-5. The lifespan of hashes and getting hex output</p><div class="example-contents"><a id="chap7_id35951994"/><pre class="programlisting">> var md5 = crypto.createHash('md5');
> md5.update('foo');
{}
> md5.digest();
'¬½\u0018ÛLÂø\\íïeOÌĤØ'
> md5.digest('hex');
Error: Not initialized
at [object Context]:1:5
at Interface.<anonymous> (repl.js:147:22)
at Interface.emit (events.js:42:17)
at Interface._onLine (readline.js:132:10)
at Interface._line (readline.js:387:8)
at Interface._ttyWrite (readline.js:564:14)
at ReadStream.<anonymous> (readline.js:52:12)
at ReadStream.emit (events.js:59:20)
at ReadStream._emitKey (tty_posix.js:280:10)
at ReadStream.onData (tty_posix.js:43:12)
> var md5 = crypto.createHash('md5');
> md5.update('foo');
{}
> md5.digest('hex');
'acbd18db4cc2f85cedef654fccc4a4d8'
></pre></div></div><p><a id="chap7_id35952004"/>When we call <code class="literal"><em class="replaceable"><code>hash</code></em>.digest()</code>
again, we get an error. This is because once <code class="literal"><em class="replaceable"><code>hash</code></em>.digest()</code> is
called, the <code class="literal">Hash</code> object is finalized
and cannot be reused. We need to create a new instance of <code class="literal">Hash</code> and use that instead. This time we get
the hex output that is often more useful. The options for <code class="literal"><em class="replaceable"><code>hash</code></em>.digest()</code>
output are <code class="literal">binary</code> (default), <code class="literal">hex</code>, and <code class="literal">base64</code>.</p><p><a id="chap7_id35952035"/>Because data in <code class="literal"><em class="replaceable"><code>hash</code></em>.update()</code> calls
is concatenated, the code samples in <a class="xref" href="ch05.html#chap7_id35952042" title="Example 5-6. Looking at how hash.update( ) concatenates input">Example 5-6</a>
are identical.</p><div class="example"><a id="chap7_id35952042"/><p class="title">Example 5-6. Looking at how hash.update( ) concatenates input</p><div class="example-contents"><a id="chap7_id35952048"/><pre class="programlisting">> var sha1 = crypto.createHash('sha1');
> sha1.update('foo');
{}
> sha1.update('bar');
{}
> sha1.digest('hex');
'8843d7f92416211de9ebb963ff4ce28125932878'
> var sha1 = crypto.createHash('sha1');
> sha1.update('foobar');
{}
> sha1.digest('hex');
'8843d7f92416211de9ebb963ff4ce28125932878'
></pre></div></div><p><a id="chap7_id35952058"/>It is also important to know that although
<code class="literal"><em class="replaceable"><code>hash</code></em>.update()</code> looks
a lot like a stream, it isn’t really. You can easily hook a stream to
<code class="literal"><em class="replaceable"><code>hash</code></em>.update()</code>, but
<a id="I_indexterm2_d1e6764" class="indexterm"/><a id="I_indexterm2_d1e6766" class="indexterm"/>you <a id="I_indexterm2_d1e6769" class="indexterm"/><a id="I_indexterm2_d1e6771" class="indexterm"/><a id="I_indexterm2_d1e6773" class="indexterm"/>can’t use <code class="literal">stream.pipe()</code>.</p></div><div class="sect2" title="HMAC"><div class="titlepage"><div><div><h2 class="title"><a id="chap7_id35952074"/>HMAC</h2></div></div></div><p><a id="chap7_id35952079"/>HMAC combines <a id="cr5.2.2" class="indexterm"/><a id="hm5.2.2" class="indexterm"/><a id="hab5.2.2" class="indexterm"/><a id="haa5.2.2" class="indexterm"/>the hashing algorithms with a cryptographic key in order
to stop a number of attacks on the integrity of the signature. This
means that HMAC uses both a hashing algorithm (such as the ones
discussed in the previous section) and an encryption key. The HMAC API
in Node is virtually identical to the <code class="literal">Hash</code> API. The only difference is that the
creation of an <code class="literal">hmac</code> object requires a
key as well as a hash algorithm.</p><p><a id="chap7_id35952092"/><code class="literal">crypto.createHmac()</code> returns <a id="I_indexterm2_d1e6812" class="indexterm"/><a id="I_indexterm2_d1e6817" class="indexterm"/>an instance of <code class="literal">Hmac</code>,
which <a id="I_indexterm2_d1e6826" class="indexterm"/><a id="I_indexterm2_d1e6831" class="indexterm"/><a id="I_indexterm2_d1e6836" class="indexterm"/>offers <code class="literal">update()</code> and
<code class="literal">digest()</code> methods that work
identically to the <code class="literal">Hash</code> methods we
saw in the previous section.</p><p><a id="chap7_id35952112"/>The key required to create an <code class="literal">Hmac</code> object is a PEM-encoded key<a id="I_indexterm2_d1e6857" class="indexterm"/><a id="I_indexterm2_d1e6860" class="indexterm"/>, passed as a string. As shown in <a class="xref" href="ch05.html#chap7_id35952119" title="Example 5-7. Creating a PEM-encoded key">Example 5-7</a>, it is easy to create a key on the command
line using<a id="I_indexterm2_d1e6868" class="indexterm"/><a id="I_indexterm2_d1e6873" class="indexterm"/> OpenSSL.</p><div class="example"><a id="chap7_id35952119"/><p class="title">Example 5-7. Creating a PEM-encoded key</p><div class="example-contents"><a id="chap7_id35952125"/><pre class="programlisting">Enki:~ $ openssl genrsa -out key.pem 1024
Generating RSA private key, 1024 bit long modulus
...++++++
............................++++++
e is 65537 (0x10001)
Enki:~ $</pre></div></div><p><a id="chap7_id35952136"/>This example creates an RSA in PEM format
and puts it into a file, in this case called <em class="filename">key.pem</em>. We also could have called the same
functionality directly from Node using the <code class="literal">process</code> module<a id="I_indexterm2_d1e6893" class="indexterm"/> (discussed later in this chapter) if we omitted the
<code class="literal">-out key.pem</code> option; with this
approach, we would get the results on an stdout stream. Instead we are
going to import the key from the file and use it to create an<a id="I_indexterm2_d1e6902" class="indexterm"/><a id="I_indexterm2_d1e6907" class="indexterm"/> <code class="literal">Hmac</code> object and a
digest (<a class="xref" href="ch05.html#chap7_id35952155" title="Example 5-8. Creating an Hmac digest">Example 5-8</a>).</p><div class="example"><a id="chap7_id35952155"/><p class="title">Example 5-8. Creating an Hmac digest</p><div class="example-contents"><a id="chap7_id35952161"/><pre class="programlisting">> var crypto = require('crypto');
> var fs = require('fs');
>
> var pem = fs.readFileSync('key.pem');
> var key = pem.toString('ascii');
>
> var hmac = crypto.createHmac('sha1', key);
>
> hmac.update('foo');
{}
> hmac.digest('hex');
'7b058f2f33ca28da3ff3c6506c978825718c7d42'
></pre></div></div><p><a id="chap7_id35952172"/>This example <a id="I_indexterm2_d1e6926" class="indexterm"/>uses <code class="literal">fs.readFileSync()</code>
because a lot of the time, loading keys will be a server setup task. As
such, it’s fine to load the keys synchronously (which might slow down
server startup time) because you aren’t serving clients yet, so blocking
the event loop is OK. In general, other than the use of the encryption
key, using an <code class="literal">Hmac</code> example is exactly
like <a id="I_indexterm2_d1e6938" class="indexterm"/><a id="I_indexterm2_d1e6940" class="indexterm"/><a id="I_indexterm2_d1e6942" class="indexterm"/><a id="I_indexterm2_d1e6944" class="indexterm"/>using a <code class="literal">Hash</code>.</p></div><div class="sect2" title="Public Key Cryptography"><div class="titlepage"><div><div><h2 class="title"><a id="chap7_id35952189"/>Public Key Cryptography</h2></div></div></div><p><a id="chap7_id35952195"/>The public key cryptography<a id="I_indexterm2_d1e6956" class="indexterm"/><a id="cr5.2.3" class="indexterm"/><a id="ke5.2.3" class="indexterm"/> functions are split into four classes: <code class="literal">Cipher</code>, <code class="literal">Decipher</code>, <code class="literal">Sign</code>, and <code class="literal">Verify</code>. Like all the other classes in <code class="literal">crypto</code>, they have factory methods. <code class="literal">Cipher</code> <a id="I_indexterm2_d1e6991" class="indexterm"/><a id="I_indexterm2_d1e6996" class="indexterm"/>encrypts data, <code class="literal">Decipher</code>
decrypts <a id="I_indexterm2_d1e7006" class="indexterm"/><a id="I_indexterm2_d1e7011" class="indexterm"/>data, <code class="literal">Sign</code> creates
<a id="I_indexterm2_d1e7020" class="indexterm"/><a id="I_indexterm2_d1e7025" class="indexterm"/>a cryptographic signature for data, and <code class="literal">Verify</code> validates <a id="I_indexterm2_d1e7034" class="indexterm"/><a id="I_indexterm2_d1e7040" class="indexterm"/>cryptographic signatures.</p><p><a id="chap7_id35952230"/>For the HMAC operations, we used a private
key. For the operations in this section, we are going to use both the
public and private keys. Public key cryptography has matched sets of
keys. One, the <a id="I_indexterm2_d1e7048" class="indexterm"/><a id="I_indexterm2_d1e7051" class="indexterm"/>private key, is kept by the owner and is used to decrypt
and sign data. The other, the public key, is made available to other
parties. The public key can be used to encrypt data that only the
private key owner can read, or to verify the signature of data signed
with the private key.</p><p><a id="chap7_id35952237"/>Let’s extract the public key of the private
key we generated to do the HMAC digests (<a class="xref" href="ch05.html#chap7_id35952242" title="Example 5-9. Extracting a public key certificate from a private key">Example 5-9</a>). Node expects public keys in certificate
format, which requires you to input additional “information.” But you
can leave all the information blank if you like.</p><div class="example"><a id="chap7_id35952242"/><p class="title">Example 5-9. Extracting a public key certificate from a private key</p><div class="example-contents"><a id="chap7_id35952248"/><pre class="programlisting">Enki:~ $ <strong class="userinput"><code>openssl req -key key.pem -new -x509 -out cert.pem</code></strong>
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgets Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:
Enki:~ $ <strong class="userinput"><code>ls cert.pem</code></strong>
cert.pem
Enki:~ $</pre></div></div><p><a id="chap7_id35952259"/>We simply ask OpenSSL to <a id="I_indexterm2_d1e7074" class="indexterm"/>read in the private key, and then output the public key
into a new file called <em class="filename">cert.pem</em> in
X509 certificate format. All of the operations in <code class="literal">crypto</code> expect keys in <a id="I_indexterm2_d1e7086" class="indexterm"/><a id="I_indexterm2_d1e7089" class="indexterm"/>PEM format.</p><div class="sect3" title="Encrypting with Cipher"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952270"/>Encrypting with Cipher</h3></div></div></div><p><a id="chap7_id35952276"/>The <code class="literal">Cipher</code> class <a id="I_indexterm2_d1e7103" class="indexterm"/><a id="I_indexterm2_d1e7108" class="indexterm"/><a id="I_indexterm2_d1e7113" class="indexterm"/>provides a wrapper for encrypting data using a private
key. The factory method to create a cipher takes an algorithm and the
private key. The algorithms supported come from those compiled into
your <a id="I_indexterm2_d1e7119" class="indexterm"/><a id="I_indexterm2_d1e7122" class="indexterm"/>OpenSSL implementation:</p><div class="itemizedlist"><a id="chap7_id35952287"/><ul class="itemizedlist"><li class="listitem"><p><a id="chap7_id35952291"/><a id="chap7_id35952292"/><code class="literal">blowfish</code></p></li><li class="listitem"><p><a id="chap7_id35952296"/><a id="chap7_id35952297"/><code class="literal">aes192</code></p></li></ul></div><p><a id="chap7_id35952301"/>Many modern cryptographic algorithms use
<a id="I_indexterm2_d1e7137" class="indexterm"/>block ciphers. This means that the output is always in
standard-size “blocks.” The block sizes vary between algorithms:
<code class="literal">blowfish</code>, for example, uses
40-byte blocks. This is significant when you are using the <code class="literal">Cipher</code> API because the API will always
output fixed-size blocks. This helps prevent information from being
leaked to an attacker about the data being encrypted or the specific
key being used to do the encryption.</p><p><a id="chap7_id35952315"/>Like <code class="literal">Hash</code> and <code class="literal">Hmac</code>, the <code class="literal">Cipher</code> API also uses the <code class="literal">update()</code> method <a id="I_indexterm2_d1e7161" class="indexterm"/>to input data. However, <code class="literal">update()</code>
works differently when used in a cipher. First, <code class="literal">cipher.update()</code> returns a block of encrypted
data if it can. This is where block size becomes important. If the
amount of data in the cipher plus the amount of data passed to
<code class="literal">cipher.update()</code> is enough to create
one or more blocks, the encrypted data will be returned. If there
isn’t enough to form a block, the input will be stored in the cipher.
<code class="literal">Cipher</code> also has a new method,
<code class="literal">cipher.final()</code>, which <a id="I_indexterm2_d1e7183" class="indexterm"/>replaces the <code class="literal">digest()</code>
method. When <code class="literal">cipher.final()</code> is
called, any remaining data in the cipher will be returned encrypted,
but with enough padding to make sure the block size is reached (see
<a class="xref" href="ch05.html#chap7_id35952371" title="Example 5-10. Ciphers and block size">Example 5-10</a>).</p><div class="example"><a id="chap7_id35952371"/><p class="title">Example 5-10. Ciphers and block size</p><div class="example-contents"><a id="chap7_id35952377"/><pre class="programlisting">> var crypto = require('crypto');
> var fs = require('fs');
>
> var pem = fs.readFileSync('key.pem');
> var key = pem.toString('ascii');
>
> var cipher = crypto.createCipher('blowfish', key);
>
> cipher.update(new Buffer(4), 'binary', 'hex');
''
> cipher.update(new Buffer(4), 'binary', 'hex');
'ff57e5f742689c85'
> cipher.update(new Buffer(4), 'binary', 'hex');
''
> cipher.final('hex')
'96576b47fe130547'
></pre></div></div><p><a id="chap7_id35952388"/>To make the example easier to read, we
specified the input and output formats. The input and output formats
are both optional and will be assumed to be binary unless specified.
For this example, we specified a binary input format because we’re
passing a new <code class="literal">Buffer</code> (containing whatever random
junk was in memory), along with hex output to produce something easier
to read. You can see that the first time we call <code class="literal">cipher.update()</code>, with 4 bytes of data, we
get back an empty string. The second time, because we have enough data
to generate a block, we get the encrypted data back as hex. When we
call <code class="literal">cipher.final()</code>, there isn’t
enough data to create a full block, so the output is padded and a full
(and final) block is returned. If we sent more data than would fit in
a single block, <code class="literal">cipher.final()</code>
would output as many blocks as it could before padding. Because
<code class="literal">cipher.final()</code> is just for
outputting existing data, it doesn’t accept an input format.</p></div><div class="sect3" title="Decrypting with Decipher"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952412"/>Decrypting with Decipher</h3></div></div></div><p><a id="chap7_id35952418"/>The <code class="literal">Decipher</code> class is almost the <a id="I_indexterm2_d1e7228" class="indexterm"/><a id="I_indexterm2_d1e7233" class="indexterm"/><a id="I_indexterm2_d1e7238" class="indexterm"/>exact inverse of the <code class="literal">Cipher</code> class. You can pass encrypted data to
a <code class="literal">Decipher</code> object using <code class="literal">decipher.update()</code>, <a id="I_indexterm2_d1e7254" class="indexterm"/>and it will stream the data into blocks until it can
output the unencrypted data. You might think that since <code class="literal">cipher.update()</code> and <code class="literal">cipher.final()</code> always give fixed-length
blocks, you would have to give perfect blocks to <code class="literal">Decipher</code>, but luckily it will buffer the
data. Thus, you can pass it data you got off some other I/O transport,
such as the disk or network, even though this might give you block
sizes different from those used by the encryption algorithm.</p><p><a id="chap7_id35952448"/>Let’s take a look at <a class="xref" href="ch05.html#chap7_id35952452" title="Example 5-11. Encrypting and decrypting text">Example 5-11</a>, which demonstrates encrypting data and
then decrypting it.</p><div class="example"><a id="chap7_id35952452"/><p class="title">Example 5-11. Encrypting and decrypting text</p><div class="example-contents"><a id="chap7_id35952457"/><pre class="programlisting">> var crypto = require('crypto');
> var fs = require('fs');
>
> var pem = fs.readFileSync('key.pem');
> var key = pem.toString('ascii');
>
> var plaintext = new Buffer('abcdefghijklmnopqrstuv');
> var encrypted = "";
> var cipher = crypto.createCipher('blowfish', key);
> ..
> encrypted += cipher.update(plaintext, 'binary', 'hex');
> encrypted += cipher.final('hex');
>
> var decrypted = "";
> var decipher = crypto.createDecipher('blowfish', key);
> decrypted += decipher.update(encrypted, 'hex', 'binary');
> decrypted += decipher.final('binary');
>
> var output = new Buffer(decrypted);
>
> output
<Buffer 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76>
> plaintext
<Buffer 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76>
></pre></div></div><p><a id="chap7_id35952467"/>It is important to make sure both the
input and output formats match up for both the plain text and the
encrypted data. It’s also worth noting that in order to get a
<code class="literal">Buffer</code>, you’ll have to make one from the strings
returned by <code class="literal">Cipher</code> and <code class="literal">Decipher</code>.</p></div><div class="sect3" title="Creating signatures using Sign"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952490"/>Creating signatures using Sign</h3></div></div></div><p><a id="chap7_id35952495"/>Signatures verify <a id="I_indexterm2_d1e7297" class="indexterm"/><a id="I_indexterm2_d1e7302" class="indexterm"/><a id="I_indexterm2_d1e7307" class="indexterm"/>that some data has been authenticated by the signer
using the private key. However, unlike with HMAC, the public key can
be used to authenticate the signature. The API for <code class="literal">Sign</code> is nearly identical to that for HMAC
(see <a class="xref" href="ch05.html#chap7_id35952519" title="Example 5-12. Signing data with Sign">Example 5-12</a>). <code class="literal">crypto.createSign()</code> is <a id="I_indexterm2_d1e7322" class="indexterm"/>used to make a <code class="literal">sign</code>
object. <code class="literal">createSign()</code> takes only the signing
algorithm. <code class="literal">sign.update()</code> allows
<a id="I_indexterm2_d1e7337" class="indexterm"/>you to add data to the <code class="literal">sign</code> object.
When you want to create the signature, call <code class="literal">sign.sign()</code> <a id="I_indexterm2_d1e7350" class="indexterm"/>with a private key to sign the data.</p><div class="example"><a id="chap7_id35952519"/><p class="title">Example 5-12. Signing data with Sign</p><div class="example-contents"><a id="chap7_id35952524"/><pre class="programlisting">> var sign = crypto.createSign('RSA-SHA256');
> sign.update('abcdef');
{}
> sig = sign.sign(key, 'hex');
'35eb47af5260a00c7bad26edfbe7732a897a3a03290963e3d17f48331a42...aa81b'
></pre></div></div></div><div class="sect3" title="Verifying signatures with Verify"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952535"/>Verifying signatures with Verify</h3></div></div></div><p><a id="chap7_id35952540"/>The <code class="literal">Verify</code> API uses a <a id="I_indexterm2_d1e7369" class="indexterm"/><a id="I_indexterm2_d1e7374" class="indexterm"/><a id="I_indexterm2_d1e7379" class="indexterm"/>method like the ones we’ve just discussed (see <a class="xref" href="ch05.html#chap7_id35952559" title="Example 5-13. Verifying signatures">Example 5-13</a>), <code class="literal">verify.update()</code>, to <a id="I_indexterm2_d1e7391" class="indexterm"/>add data—and when you have added all the data to be
verified against the signature, <code class="literal">verify.verify()</code> <a id="I_indexterm2_d1e7400" class="indexterm"/>validates the signature. It takes the <code class="literal">cert</code> (the public key), the signature, and
the format of the <a id="I_indexterm2_d1e7409" class="indexterm"/><a id="I_indexterm2_d1e7411" class="indexterm"/>signature.</p><div class="example"><a id="chap7_id35952559"/><p class="title">Example 5-13. Verifying signatures</p><div class="example-contents"><a id="chap7_id35952564"/><pre class="programlisting">> var crypto = require('crypto');
> var fs = require('fs');
>
> var privatePem = fs.readFileSync('key.pem');
> var publicPem = fs.readFileSync('cert.pem');
> var key = privatePem.toString();
> var pubkey = publicPem.toString();
>
> var data = "abcdef"
>
> var sign = crypto.createSign('RSA-SHA256');
> sign.update(data);
{}
> var sig = sign.sign(key, 'hex');
>
> var verify = crypto.createVerify('RSA-SHA256');
> verify.update(data);
{}
> verify.verify(pubkey, sig, 'hex');
1</pre></div></div></div></div></div><div class="sect1" title="Processes"><div class="titlepage"><div><div><h1 class="title"><a id="chap7_id35952580"/>Processes</h1></div></div></div><p><a id="chap7_id35952585"/>Although Node abstracts a lot of things from
the operating system, you are still running in an operating system and may
want to interact more directly with it. Node allows you to interact with
system processes that already exist, as well as create new child processes
to do work of various kinds. Although Node itself is generally a “fat”
thread with a single event loop, you are free to start other processes
(threads) to do work outside of the event loop.</p><div class="sect2" title="process Module"><div class="titlepage"><div><div><h2 class="title"><a id="chap7_id35952592"/>process Module</h2></div></div></div><p><a id="chap7_id35952597"/>The <code class="literal">process</code> module <a id="I_indexterm2_d1e7432" class="indexterm"/>enables you to get information about and change the
settings of the current Node process. Unlike most modules, the <code class="literal">process</code> module is global and is always
available as the variable <code class="literal">process</code>.</p><div class="sect3" title="process events"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952612"/>process events</h3></div></div></div><p><a id="chap7_id35952617"/><code class="literal">process</code>
is an instance of <code class="literal">EventEmitter</code>,
<a id="I_indexterm2_d1e7455" class="indexterm"/><a id="I_indexterm2_d1e7460" class="indexterm"/>so it provides events based on systems calls to the Node
process. The <code class="literal">exit</code> event <a id="I_indexterm2_d1e7469" class="indexterm"/><a id="I_indexterm2_d1e7474" class="indexterm"/>provides a final hook before the Node process exits (see
<a class="xref" href="ch05.html#chap7_id35952635" title="Example 5-14. Calling code when Node is exiting">Example 5-14</a>). Importantly, the event loop will
not run after the <code class="literal">exit</code> event, so
only code without callbacks will be executed.</p><div class="example"><a id="chap7_id35952635"/><p class="title">Example 5-14. Calling code when Node is exiting</p><div class="example-contents"><a id="chap7_id35952640"/><pre class="programlisting">process.on('exit', function () {
setTimeout(function () {
console.log('This will not run');
}, 100);
console.log('Bye.');
});</pre></div></div><p><a id="chap7_id35952651"/>Because the loop isn’t going to run again,
the <code class="literal">setTimeout()</code> code will never be
evaluated.</p><p><a id="chap7_id35952658"/>An extremely useful event <a id="I_indexterm2_d1e7496" class="indexterm"/><a id="I_indexterm2_d1e7501" class="indexterm"/>provided by <code class="literal">process</code>
is <code class="literal">uncaughtException</code> (<a class="xref" href="ch05.html#chap7_id35952675" title="Example 5-15. Trapping an exception with the uncaughtException event">Example 5-15</a>). After you’ve spent any time with Node,
you’ll find that exceptions that hit the main event loop will kill
your Node process. In many use cases, especially servers that are
expected to never be down, this is unacceptable. The <code class="literal">uncaughtException</code> event provides an
extremely brute-force way of catching these exceptions. It’s really a
last line of defense, but it’s extremely useful for that
purpose.</p><div class="example"><a id="chap7_id35952675"/><p class="title">Example 5-15. Trapping an exception with the uncaughtException
event</p><div class="example-contents"><a id="chap7_id35952681"/><pre class="programlisting">process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
setTimeout(function () {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');</pre></div></div><p><a id="chap7_id35952692"/>Let’s break
down what’s happening. First, we create an event listener for <code class="literal">uncaught</code><code class="literal">Exception</code>. This is not a smart handler;
it simply outputs the exception to stdout. If this Node script were
running as a server, stdout could easily be used to save the log into
a file and capture these errors. However, because it captures the
event for a nonexistent function, Node will not exit, but the standard
flow is still disrupted. We know that all the JavaScript runs once,
and then any callbacks will be run each time their event listener
emits an event. In this scenario, because <code class="literal">nonexistentFunc()</code> will throw an exception,
no code following it will be called. However, any code that has
already been run will continue to run. This means that <code class="literal">setTimeout()</code> will still call. This is
significant when you’re writing servers. Let’s consider some more code
in this area, shown in <a class="xref" href="ch05.html#process_exception_catch" title="Example 5-16. The effect on callbacks of catching exceptions">Example 5-16</a>.</p><div class="example"><a id="process_exception_catch"/><p class="title">Example 5-16. The effect on callbacks of catching exceptions</p><div class="example-contents"><a id="chap7_id35952720"/><pre class="programlisting">var http = require('http');
var server = http.createServer(function(req,res) {
res.writeHead(200, {});
res.end('response');
badLoggingCall('sent response');
console.log('sent response');
});
process.on('uncaughtException', function(e) {
console.log(e);
});
server.listen(8080);</pre></div></div><p><a id="chap7_id35952731"/>This code creates a simple HTTP server and
then listens for any uncaught exceptions at the process level. In our
HTTP server, the callback deliberately calls a bad function after
we’ve sent the HTTP response. <a class="xref" href="ch05.html#chap7_id35952737" title="Example 5-17. Output of Example 5-16">Example 5-17</a>
shows the console output for this script.</p><div class="example"><a id="chap7_id35952737"/><p class="title">Example 5-17. Output of <a class="xref" href="ch05.html#process_exception_catch" title="Example 5-16. The effect on callbacks of catching exceptions">Example 5-16</a></p><div class="example-contents"><a id="chap7_id35952745"/><pre class="programlisting">Enki:~ $ <strong class="userinput"><code>node ex-test.js</code></strong>
{ stack: [Getter/Setter],
arguments: [ 'badLoggingCall' ],
type: 'not_defined',
message: [Getter/Setter] }
{ stack: [Getter/Setter],
arguments: [ 'badLoggingCall' ],
type: 'not_defined',
message: [Getter/Setter] }
{ stack: [Getter/Setter],
arguments: [ 'badLoggingCall' ],
type: 'not_defined',
message: [Getter/Setter] }
{ stack: [Getter/Setter],
arguments: [ 'badLoggingCall' ],
type: 'not_defined',
message: [Getter/Setter] }</pre></div></div><p><a id="chap7_id35952756"/>When we start the example script, the
server is available, and we have made a number of HTTP requests to it.
Notice that the server doesn’t shut down at any point. Instead, the
errors are logged using the function attached to <a id="I_indexterm2_d1e7557" class="indexterm"/><a id="I_indexterm2_d1e7562" class="indexterm"/>the <code class="literal">uncaughtException</code>
event. However, we are still serving complete HTTP requests. Why? Node
deliberately prevented the callback in <code class="literal">process</code> from proceeding and calling <code class="literal">console.log()</code>. The error affected only the
process we spawned and the server kept running, so any other code was
unaffected by the exception encapsulated in one specific code
path.</p><p><a id="chap7_id35952777"/>It’s important to understand the way that
listeners are <a id="I_indexterm2_d1e7578" class="indexterm"/>implemented in Node. Let’s take a look at <a class="xref" href="ch05.html#chap7_id35952781" title="Example 5-18. The abbreviated listener code for EventEmitter">Example 5-18</a>.</p><div class="example"><a id="chap7_id35952781"/><p class="title">Example 5-18. The abbreviated listener code for EventEmitter</p><div class="example-contents"><a id="chap7_id35952787"/><pre class="programlisting">EventEmitter.prototype.emit = function(type) {
...
var handler = this._events[type];
...
} else if (isArray(handler)) {
var args = Array.prototype.slice.call(arguments, 1);
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
}
return true;
...
};</pre></div></div><p><a id="chap7_id35952798"/>After an event is emitted, one of the
checks in the runtime handler is to see whether there is an array of
listeners. If there is more than one listener, the runtime calls the
listeners by looping through the array in order. This means that the
first attached listener will be called first with <code class="literal">apply()</code>, then the second, and so on. What’s
important to note here is that <span class="emphasis"><em>all</em></span> listeners on
the same event are part of the same code path. So an uncaught
exception in one callback will stop execution for all other callbacks
on the same event. However, an uncaught exception in one instance of
an event won’t affect other events.</p><p><a id="chap7_id35952812"/>We also get access to a number of system
events through <code class="literal">process</code>. When the
process gets a signal, it is exposed to Node via events emitted by
<code class="literal">process</code>. An operating system can
generate a lot of POSIX system events, which can be found in the
<span class="emphasis"><em>sigaction(2)</em></span> manpage. Really common ones
include<a id="I_indexterm2_d1e7610" class="indexterm"/> SIGINT, the interrupt signal. Typically, a SIGINT is what happens when you press
Ctrl-C in the terminal on a running process. Unless you handle the
signal events via <code class="literal">process</code>, Node
will just perform the default action; in the case of a SIGINT, the
default is to immediately kill the process. You can change default
behavior (except for a couple of signals that can never get caught)
through the <code class="literal">process.on()</code> method
(<a class="xref" href="ch05.html#chap7_id35952837" title="Example 5-19. Catching signals to the Node process">Example 5-19</a>).</p><div class="example"><a id="chap7_id35952837"/><p class="title">Example 5-19. Catching signals to the Node process</p><div class="example-contents"><a id="chap7_id35952668"/><pre class="programlisting">// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});</pre></div></div><p><a id="chap7_id35952856"/>To make sure Node doesn’t exit on its own,
we read from stdin (described in <a class="xref" href="ch05.html#process_io_stream" title="Operating system input/output">Operating system input/output</a>)
so the Node process continues to run. If you Ctrl-C the program while
it’s running, the operating system (OS) will send a SIGINT to Node,
which will be caught by the SIGINT event handler. Here, instead of
exiting, we log to the console instead.</p></div><div class="sect3" title="Interacting with the current Node process"><div class="titlepage"><div><div><h3 class="title"><a id="chap7_id35952867"/>Interacting with the current Node process</h3></div></div></div><p><a id="chap7_id35952873"/><code class="literal">Process</code> contains a lot
of meta-information about the Node process. This can be very helpful
when you need to manage your Node environment from within the process.
There are a number of properties that contain immutable (read-only)
information about Node, such as:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">process.version</code></span></dt><dd><p><a id="chap7_id35952887"/><a id="chap7_id35952889"/>Contains the version number of the
<a id="I_indexterm2_d1e7650" class="indexterm"/>instance of Node you are running.</p></dd><dt><span class="term"><code