sodium-prebuilt
Version:
Prebuilds for Lib Sodium port for node.js
161 lines (134 loc) • 5.25 kB
JavaScript
/**
* Created by bmf on 11/2/13.
*
* Documentation of crypto http://nacl.cr.yp.to/box.html
*/
/* jslint node: true */
'use strict';
var binding = require('../build/Release/sodium');
var assert = require('assert');
var toBuffer = require('./toBuffer');
var SecretBoxKey = require('./keys/secretbox-key');
var Nonce = require('./nonces/secretbox-nonce');
/**
* Public-key authenticated encryption: Box
*
* @param {String|Buffer|Array} secretKey sender's private key.
* @param {String|Buffer|Array} publicKey recipient's private key.
*
* @see Keys
* @constructor
*/
module.exports = function SecretBox(secretKey, encoding) {
var self = this;
/** default encoding to use in all string operations */
self.defaultEncoding = undefined;
if( secretKey instanceof SecretBoxKey) {
self.boxKey = secretKey;
}
else {
/** Set the keys used to encrypt and decrypt messages */
self.boxKey = new SecretBoxKey(secretKey, encoding);
}
/** SecretBox padding of cipher text buffer */
self.boxZeroBytes = function() {
return binding.crypto_secretbox_BOXZEROBYTES;
};
/** Passing of message. This implementation does message padding automatically */
self.zeroBytes = function() {
return binding.crypto_secretbox_ZEROBYTES;
};
/** String name of the default crypto primitive used in secretbox operations */
self.primitive = function() {
return binding.crypto_secretbox_PRIMITIVE;
};
/**
* Get the box-key secret key object
* @returns {BoxKey|*}
*/
self.key = function() {
return self.boxKey;
};
/**
* Set the default encoding to use in all string conversions
* @param {String} encoding encoding to use
*/
self.setEncoding = function(encoding) {
assert(!!encoding.match(/^(?:utf8|ascii|binary|hex|utf16le|ucs2|base64)$/), 'Encoding ' + encoding + ' is currently unsupported.');
self.defaultEncoding = encoding;
};
/**
* Get the current default encoding
* @returns {undefined|String}
*/
self.getEncoding = function() {
return self.defaultEncoding;
};
/**
* Encrypt a message
* The crypto_secretbox function is designed to meet the standard notions of
* privacy and authenticity for a secret-key authenticated-encryption scheme
* using nonces. For formal definitions see, e.g., Bellare and Namprempre,
* "Authenticated encryption: relations among notions and analysis of the
* generic composition paradigm," Lecture Notes in Computer Science
* 1976 (2000), 531–545, http://www-cse.ucsd.edu/~mihir/papers/oem.html.
*
* Note that the length is not hidden. The basic API leaves it up to the
* caller to generate a unique nonce for every message, in the high level
* API a random nonce is generated automatically and you do no need to
* worry about it.
*
* If no options are given a new random nonce will be generated automatically
* and both planText and cipherText must be buffers
*
* @param {Buffer|String|Array} plainText message to encrypt
* @param {String} [encoding] encoding of message string
*
* @returns {Object} cipher box
*/
self.encrypt = function (plainText, encoding) {
encoding = encoding || self.defaultEncoding;
// generate a new random nonce
var nonce = new Nonce();
var buf = toBuffer(plainText, encoding);
var cipherText = binding.crypto_secretbox(
buf,
nonce.get(),
self.boxKey.get());
if( !cipherText ) {
return undefined;
}
return {
cipherText: cipherText,
nonce : nonce.get()
};
};
/**
* The decrypt function verifies and decrypts a cipherText using the
* receiver's secret key, the sender's public key, and a nonce.
* The function returns the resulting plaintext m.
*
* @param {Buffer|String|Array} cipherText the encrypted message
* @param {Buffer|String|Array} nonce the nonce used to encrypt
* @param {String} [encoding] the encoding to used in cipherText, nonce, plainText
*/
self.decrypt = function (cipherBox, encoding) {
encoding = String(encoding || self.defaultEncoding);
assert(typeof cipherBox == 'object' && cipherBox.hasOwnProperty('cipherText') && cipherBox.hasOwnProperty('nonce'), 'cipherBox is an object with properties `cipherText` and `nonce`.');
assert(cipherBox.cipherText instanceof Buffer, 'cipherBox should have a cipherText property that is a buffer') ;
assert(cipherBox.nonce instanceof Buffer, 'cipherBox should have a nonce property that is a buffer') ;
var nonce = new Nonce(cipherBox.nonce);
var plainText = binding.crypto_secretbox_open(
cipherBox.cipherText,
nonce.get(),
self.boxKey.get()
);
if( plainText && encoding ) {
return plainText.toString(encoding);
}
return plainText;
};
// Aliases
self.close = self.encrypt;
self.open = self.decrypt;
};