Ursa
URSA - RSA public/private key OpenSSL bindings for Node.js
Install / Use
/learn @JoshKaufman/UrsaREADME
URSA - RSA public/private key OpenSSL bindings for Node.js
NOTE: This package was transfered from Medium and NodePrime to quartzjer to JoshKaufman on 8-2017. Pull requests are welcomed to help maintain it.
--
This Node module provides a fairly complete set of wrappers for the RSA public/private key crypto functionality of OpenSSL.
It is being actively developed for node.js 0.8.* through 0.12.* and io.js. If you find it doesn't work for you, please file a bug (see below).
It has been tested on Windows by SLaks. (see additional installation requirements)
Table of Contents
- Simple Encrypt / Decrypt Example
- Building and Installing
- Usage
- Top-level Exports
- Public Key Methods
- Private Key Methods
- Signer Methods
- Verifier Methods
- Constants
- Contributing
- Authors
- License
- Related Repos
Simple Encrypt / Decrypt Example
// openssl genrsa -out certs/server/my-server.key.pem 2048
// openssl rsa -in certs/server/my-server.key.pem -pubout -out certs/client/my-server.pub
'use strict';
var fs = require('fs')
, ursa = require('ursa')
, crt
, key
, msg
;
key = ursa.createPrivateKey(fs.readFileSync('./certs/server/my-server.key.pem'));
crt = ursa.createPublicKey(fs.readFileSync('./certs/client/my-server.pub'));
console.log('Encrypt with Public');
msg = crt.encrypt("Everything is going to be 200 OK", 'utf8', 'base64');
console.log('encrypted', msg, '\n');
console.log('Decrypt with Private');
msg = key.decrypt(msg, 'base64', 'utf8');
console.log('decrypted', msg, '\n');
console.log('############################################');
console.log('Reverse Public -> Private, Private -> Public');
console.log('############################################\n');
console.log('Encrypt with Private (called public)');
msg = key.privateEncrypt("Everything is going to be 200 OK", 'utf8', 'base64');
console.log('encrypted', msg, '\n');
console.log('Decrypt with Public (called private)');
msg = crt.publicDecrypt(msg, 'base64', 'utf8');
console.log('decrypted', msg, '\n');
Building and Installing
npm install ursa
Or grab the source and
npm install
Testing
npm test
Or
node ./test/test.js
<a id="windows-install"></a> On Windows, you'll need to install some dependencies first:
- OpenSSL (normal, not light) in the same bitness as your Node.js installation.
- OpenSSL must be installed in the a specific install directory (
C:\OpenSSL-Win32orC:\OpenSSL-Win64) - If you get
Error: The specified module could not be found., copylibeay32.dllfrom the OpenSSL bin directory to this module's bin directory, or to Windows\System32. - node-gyp (
npm install -g node-gyp)- You will need python 2.7 and a compatible version
Visual Studio installed first. Even with that,
node-gypinstallation or use can have issues on Windows. Thenode-gypREADME file has detailed instructions if you have difficulties. This post is also a good reference.
- You will need python 2.7 and a compatible version
Visual Studio installed first. Even with that,
Usage
This library aims to be convenient to use, allowing one to pass in and get back regular string objects. However, it is also meant to be reasonably easy to use efficiently, allowing one to pass in and get back Buffer objects. Using Buffers is always the more efficient option.
All methods that can deal with strings take one or more arguments indicating
the encoding to use when interpreting an argument or generating a result.
These are limited to the usual encoding names that are valid for use with
Buffers: base64 binary hex and utf8. If an encoding is left undefined
and the argument is a string, then the encoding is always assumed to be
utf8. If an argument is a Buffer, then the encoding (if defined at all)
is ignored. An undefined output encoding is always interpreted as a request
for a Buffer result.
The library knows how to read and output PEM format files for both public and private keys, and it can generate new private keys (aka keypairs).
The usual public-encryption / private-decryption operations by default
use padding mode RSA_PKCS1_OAEP_PADDING, which is the recommended
mode for all new applications (as of this writing). Note that this mode
builds-in a random element into every encryption operation, making it
unnecessary to waste time or effort adding randomness in at a higher layer.
This default may be overridden to use the older mode RSA_PKCS1_PADDING
if needed.
The less well-understood private-encryption / public-decryption operations
(used for building signature mechanisms) by default use padding
mode RSA_PKCS1_PADDING. This doesn't build in any randomness (but that's
not usually a problem for applications that use these operations). This
default may be overridden to use RSA_NO_PADDING if needed.
See the doc comments and tests for the excruciating details, but here's a quick rundown of the available top-level exports and instance methods:
Top-Level Exports
ursa.createPrivateKey(pem, password, encoding)
Create and return a private key (aka a keypair) read in from the given PEM-format file. If defined, the given password is used to decrypt the PEM file.
The encoding, if specified, applies to both other arguments.
See "Public Key Methods" below for more details.
ursa.createPrivateKeyFromComponents(modulus, exponent, p, q, dp, dq, inverseQ, d)
Create and return a private key from the given components.
ursa.createPublicKeyFromComponents(modulus, exponent)
Create and return a public key from the given components.
ursa.assertKey(obj)
Convenient shorthand for assert(ursa.isKey(obj)).
ursa.assertPrivateKey(obj)
Convenient shorthand for assert(ursa.isPrivateKey(obj)).
ursa.assertPublicKey(obj)
Convenient shorthand for assert(ursa.isPublicKey(obj)).
ursa.coerceKey(orig)
Coerce the given key value into a key object (either public or private), returning it. If given a private key object, this just returns it as-is. If given a string or Buffer, it tries to parse it as PEM. Anything else will result in an error.
ursa.coercePrivateKey(orig)
Coerce the given key value into a private key object, returning it. If given a private key object, this just returns it as-is. If given a string or Buffer, it tries to parse it as PEM. Anything else will result in an error.
ursa.coercePublicKey(orig)
Coerce the given key value into a public key object, returning it. If given a private key object, this just returns it as-is. If given a string or Buffer, it tries to parse it as PEM. Anything else will result in an error.
ursa.createPublicKey(pem, encoding)
Create and return a public key read in from the given PEM-format file. See "Public Key Methods" below for more details.
ursa.createSigner(algorithm)
Create and return a signer which can sign a hash generated with the named
algorithm (such as "sha256" or "md5"). See "Signer Methods" below
for more details.
This function is similar to crypto.createSign(), except this function
takes a hash algorithm name (e.g., "sha256") and not a crypto+hash name
combination (e.g., "RSA-SHA256").
ursa.createVerifier(algorithm)
Create and return a verifier which can verify a hash generated with the
named algorithm (such as "sha256" or "md5"). See "Verifier Methods" below
for more details.
This function is similar to crypto.createVerify(), except this function
takes a hash algorithm name (e.g., "sha256") and not a crypto+hash name
combination (e.g., "RSA-SHA256").
ursa.equalKeys(key1, key2)
This returns true if and only if both arguments are key objects of
the same type (public or private) and their contents match.
ursa.generatePrivateKey(modulusBits, exponent)
Create and return a freshly-generated private key (aka a keypair). The first argument indicates the number of bits in the modulus (1024 or more is generally considered secure). The second argument indicates the exponent value, which must be odd (65537 is the typical value; 3 and 17 are also common). Both arguments are optional and default to 2048 and 65537 (respectively).
This method will throw if modulusBits is less than 512 (because
it's pretty crazy to want a key with that few bits) or if exponent
is even (because RSA only works for odd exponents).
Using the command-line openssl tool, this operation is
equivalent to:
openssl genrsa -out key-name.pem <modulusBits>
for exponent 65537, or for exponent 3 with the additional option
-3. (That tool doesn't support other exponents.)
ursa.isKey(obj)
Return true if the given object is a key object (public or private) that
was created by this module. Return false if not.
ursa.isPrivateKey(obj)
Return true if the given object is a private key object that
was created by this module. Return false if not.
ursa.isPublicKey(obj)
Return true if the given object is a public key object that
was created by this module. Return false if not.
Note that, even though all the public key operations work on private keys, this function only ret
