-
Notifications
You must be signed in to change notification settings - Fork 127
/
secretbox.js
executable file
·157 lines (134 loc) · 5.13 KB
/
secretbox.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* 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;
};