node-secure-stream
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -35,3 +35,3 @@ /* | ||
const dec = new SecureStreams.Decrypter({key: private_key}); | ||
const dec = new SecureStreams.Decrypter({private_key: private_key}); | ||
@@ -52,3 +52,3 @@ return input.pipe(dec).pipe(concat(function(data) { | ||
const dec = new SecureStreams.Decrypter({key: private_key}); | ||
const dec = new SecureStreams.Decrypter({private_key: private_key}); | ||
@@ -55,0 +55,0 @@ return input.pipe(dec).pipe(concat(function(data) { |
@@ -18,7 +18,7 @@ /* | ||
it('should securely roundtrip a short string', function(done) { | ||
it('should securely roundtrip a short string, public to private', function(done) { | ||
const input = 'your text here'; | ||
const input_stream = StringToStream([input]); | ||
const enc = new SecureStreams.Encrypter({public_key}); | ||
const dec = new SecureStreams.Decrypter({key: private_key}); | ||
const dec = new SecureStreams.Decrypter({private_key: private_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
@@ -32,7 +32,7 @@ expect(data).toBeDefined(); | ||
it('should securely roundtrip a UTF8 string', function(done) { | ||
it('should securely roundtrip a UTF8 string, public to private', function(done) { | ||
const input = 'your \u201ctext\u201d here'; | ||
const input_stream = StringToStream([input]); | ||
const enc = new SecureStreams.Encrypter({public_key}); | ||
const dec = new SecureStreams.Decrypter({key: private_key}); | ||
const dec = new SecureStreams.Decrypter({private_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
@@ -46,7 +46,7 @@ expect(data).toBeDefined(); | ||
return it('should securely roundtrip a file', function(done) { | ||
it('should securely roundtrip a file, public to private', function(done) { | ||
const buffer = fs.readFileSync('./__tests__/data/darwin-sm.png'); | ||
const input_stream = StringToStream([buffer]); | ||
const enc = new SecureStreams.Encrypter({public_key}); | ||
const dec = new SecureStreams.Decrypter({key: private_key}); | ||
const dec = new SecureStreams.Decrypter({private_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
@@ -59,2 +59,42 @@ expect(data).toBeDefined(); | ||
}); | ||
it('should securely roundtrip a short string, private to public', function(done) { | ||
const input = 'your text here'; | ||
const input_stream = StringToStream([input]); | ||
const enc = new SecureStreams.Encrypter({private_key}); | ||
const dec = new SecureStreams.Decrypter({public_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
expect(data).toBeDefined(); | ||
expect(data.toString()).toEqual(input); | ||
return done(); | ||
}) | ||
); | ||
}); | ||
it('should securely roundtrip a UTF8 string, private to public', function(done) { | ||
const input = 'your \u201ctext\u201d here'; | ||
const input_stream = StringToStream([input]); | ||
const enc = new SecureStreams.Encrypter({private_key}); | ||
const dec = new SecureStreams.Decrypter({public_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
expect(data).toBeDefined(); | ||
expect(data.toString()).toEqual(input); | ||
return done(); | ||
}) | ||
); | ||
}); | ||
it('should securely roundtrip a file, private to public', function(done) { | ||
const buffer = fs.readFileSync('./__tests__/data/darwin-sm.png'); | ||
const input_stream = StringToStream([buffer]); | ||
const enc = new SecureStreams.Encrypter({private_key}); | ||
const dec = new SecureStreams.Decrypter({public_key}); | ||
return input_stream.pipe(enc).pipe(dec).pipe(concat(function(data) { | ||
expect(data).toBeDefined(); | ||
expect(data.toString('hex')).toEqual(buffer.toString('hex')); | ||
return done(); | ||
}) | ||
); | ||
}); | ||
}); |
## Change log | ||
### Version 0.2.0 - 16th January 2019 | ||
* Allow private -> public and public -> private encryption modes | ||
* Breaking API change: private key for decryption is under `private_key` option, not `key` | ||
### Version 0.1.1 - 13th December 2018 | ||
@@ -5,0 +11,0 @@ |
106
lib/index.js
@@ -1,7 +0,9 @@ | ||
/* | ||
* decaffeinate suggestions: | ||
* DS102: Remove unnecessary code created because of implicit returns | ||
* DS207: Consider shorter variations of null checks | ||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md | ||
/** | ||
* A simple JavaScript module for allowing decryption and encryption | ||
* using RSA, for streams rather than strings. Works by generating an | ||
* AES256 key, and then securing that with RSA. | ||
* | ||
* Author: Stuart Watt <stuart@morungos.com> | ||
*/ | ||
const crypto = require('crypto'); | ||
@@ -18,14 +20,16 @@ | ||
this.algorithm = options.algorithm; | ||
if (this.algorithm == null) { | ||
if (! this.algorithm) { | ||
this.algorithm = 'AES-256-CBC'; | ||
} | ||
this.key_length = options.key_length; | ||
if (this.key_length == null) { | ||
if (! this.key_length) { | ||
this.key_length = 256; | ||
} | ||
this.public_key = options.public_key; | ||
this.key = options.key; | ||
if (!this.public_key) { | ||
throw new Error("Missing public key"); | ||
if (options.public_key) { | ||
this.public_key = options.public_key; | ||
} else if (options.private_key) { | ||
this.private_key = options.private_key; | ||
} else { | ||
throw new Error("Missing key: please specify either public_key or private_key"); | ||
} | ||
@@ -45,11 +49,11 @@ } | ||
const key = keys.slice(16); | ||
// logger.debug "KEY", key | ||
// logger.debug "IV", iv | ||
// logger.debug("KEY", key) | ||
// logger.debug("IV", iv) | ||
// Make a regular cipher object. This handles the writing of all | ||
// subsequent data. | ||
// logger.debug "initialize createCipheriv", @algorithm, key, iv | ||
// logger.debug("initialize createCipheriv", this.algorithm, key, iv) | ||
this.cipher = crypto.createCipheriv(this.algorithm, key, iv); | ||
this.cipher.on('data', buffer => | ||
// logger.debug 'cipher data', buffer | ||
// logger.debug('cipher data', buffer) | ||
self.push(buffer) | ||
@@ -60,3 +64,5 @@ ); | ||
// Now, we need to manage the RSA handling of the AES key. | ||
const encrypted_key = crypto.publicEncrypt(this.public_key, key); | ||
let encrypted_key = (this.public_key) | ||
? crypto.publicEncrypt(this.public_key, key) | ||
: crypto.privateEncrypt(this.private_key, key); | ||
@@ -92,5 +98,5 @@ const header = Buffer.alloc(4096); | ||
// logger.debug "Encrypter _write", chunk, encoding | ||
// logger.debug("Encrypter _write", chunk, encoding) | ||
this.cipher.write(chunk, encoding, () => | ||
// logger.debug "Encrypter write cipher result", result | ||
// logger.debug("Encrypter write cipher result", result) | ||
callback() | ||
@@ -102,5 +108,5 @@ ); | ||
_flush(callback) { | ||
// logger.debug "Encrypter _flush" | ||
// logger.debug("Encrypter _flush") | ||
this.cipher.end(() => | ||
// logger.debug "Encrypter _flush complete" | ||
// logger.debug("Encrypter _flush complete") | ||
callback() | ||
@@ -118,6 +124,13 @@ ); | ||
this.header_complete = false; | ||
this.key = options.key; | ||
this.header = Buffer.alloc(4096); | ||
this.header_size = 0; | ||
this.header_index = 0; | ||
if (options.public_key) { | ||
this.public_key = options.public_key; | ||
} else if (options.private_key) { | ||
this.private_key = options.private_key; | ||
} else { | ||
throw new Error("Missing key: please specify either public_key or private_key"); | ||
} | ||
} | ||
@@ -130,32 +143,35 @@ | ||
this.header_size = this.header.readInt16LE(index); | ||
// logger.debug "unpackHeader @header_size", @header_size | ||
// logger.debug("unpackHeader @header_size", this.header_size) | ||
index = index + 2; | ||
const algorithm_size = this.header.readInt16LE(index); | ||
// logger.debug "unpackHeader algorithm_size", algorithm_size | ||
// logger.debug("unpackHeader algorithm_size", algorithm_size) | ||
index = index + 2; | ||
this.algorithm = this.header.slice(index, index + algorithm_size).toString('latin1'); | ||
// logger.debug "unpackHeader @algorithm", @algorithm | ||
// logger.debug("unpackHeader @algorithm", this.algorithm) | ||
index = index + algorithm_size; | ||
const encrypted_key_size = this.header.readInt16LE(index); | ||
// logger.debug "unpackHeader encrypted_key_size", encrypted_key_size | ||
// logger.debug("unpackHeader encrypted_key_size", encrypted_key_size) | ||
index = index + 2; | ||
const encrypted_key = this.header.slice(index, index + encrypted_key_size); | ||
// logger.debug "unpackHeader encrypted_key", encrypted_key | ||
// logger.debug("unpackHeader encrypted_key", encrypted_key) | ||
index = index + encrypted_key_size; | ||
const iv_size = this.header.readInt16LE(index); | ||
// logger.debug "unpackHeader iv_size", iv_size | ||
// logger.debug("unpackHeader iv_size", iv_size) | ||
index = index + 2; | ||
this.iv = this.header.slice(index, index + iv_size); | ||
// logger.debug "unpackHeader @iv", @iv | ||
// logger.debug("unpackHeader @iv", this.iv) | ||
index = index + iv_size; | ||
//# Now, let's decrypted the key, and build a decryption cipher | ||
this.key = crypto.privateDecrypt(this.key, encrypted_key); | ||
// logger.debug "unpackHeader decrypted", encrypted_key, 'to', @key | ||
// Now, let's decrypted the key, and build a decryption cipher | ||
// logger.debug("unpackHeader decrypted", encrypted_key, 'to', this.key) | ||
let decrypted_key = (this.public_key) | ||
? crypto.publicDecrypt(this.public_key, encrypted_key) | ||
: crypto.privateDecrypt(this.private_key, encrypted_key); | ||
//# And here's the new cipher | ||
// logger.debug "unpackHeader createDecipheriv", @algorithm, @key, @iv | ||
this.cipher = crypto.createDecipheriv(this.algorithm, this.key, this.iv); | ||
// And here's the new cipher | ||
// logger.debug("unpackHeader createDecipheriv", this.algorithm, this.key, this.iv) | ||
this.cipher = crypto.createDecipheriv(this.algorithm, decrypted_key, this.iv); | ||
this.cipher.on('data', buffer => | ||
// logger.debug 'cipher data', buffer | ||
// logger.debug('cipher data', buffer) | ||
self.push(buffer) | ||
@@ -165,3 +181,3 @@ ); | ||
// logger.debug "unpackHeader done" | ||
// logger.debug("unpackHeader done") | ||
this.header_complete = true; | ||
@@ -174,3 +190,3 @@ } | ||
chunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding); | ||
// logger.debug "Got chunk", chunk, encoding | ||
// logger.debug("Got chunk", chunk, encoding) | ||
@@ -180,7 +196,7 @@ if (!this.header_complete) { | ||
this.header_index = this.header_index + chunk.length; | ||
// logger.debug "Added chunk", @header_index, chunk | ||
// logger.debug("Added chunk", this.header_index, chunk) | ||
if (this.header_index >= 2) { | ||
this.header_size = this.header.readInt16LE(0); | ||
// logger.debug "Worked out @header_size", @header_size | ||
// logger.debug("Worked out this.header_size", this.header_size) | ||
} else { | ||
@@ -191,3 +207,3 @@ callback(); | ||
if ((this.header_size == null) || (this.header_index < this.header_size)) { | ||
if (! this.header_size || (this.header_index < this.header_size)) { | ||
callback(); | ||
@@ -197,3 +213,3 @@ return; | ||
// logger.debug 'XXXX', @header_size, @header_index, chunk.length | ||
// logger.debug('XXXX', this.header_size, this.header_index, chunk.length) | ||
@@ -207,7 +223,7 @@ const header_buffer = this.header.slice(0, this.header_size); | ||
// logger.debug "Remaining", chunk, chunk.length | ||
// logger.debug("Remaining", chunk, chunk.length) | ||
//# We might well have a bit of chunk left over, so if we do, let's | ||
//# chop if off and run it through the cipher. This isn't just a block | ||
//# after 4096, it depends on the header block size. | ||
// We might well have a bit of chunk left over, so if we do, let's | ||
// chop if off and run it through the cipher. This isn't just a block | ||
// after 4096, it depends on the header block size. | ||
@@ -214,0 +230,0 @@ this.cipher.write(chunk, encoding, () => callback()); |
{ | ||
"name": "node-secure-stream", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Stream-based encryption for large amounts of data", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "mocha --sort --recursive --compilers coffee:coffee-script/register $(find test -name '*_test.*')", | ||
"build": "coffee -b -o lib src" | ||
"test": "jest", | ||
"test-watch": "jest --watch" | ||
}, | ||
@@ -10,0 +10,0 @@ "repository": { |
@@ -29,2 +29,12 @@ # node-secure-stream | ||
or, to use a private key for encryption: | ||
var SecureStreams = require('node-secure-stream'); | ||
var fs = require('fs'); | ||
var private_key = fs.readFileSync(__dirname + '/files/private'); | ||
var enc = new SecureStreams.Encrypter({private_key: private_key}) | ||
process.stdin.pipe(enc).pipe(process.stdout); | ||
For decryption: | ||
@@ -36,5 +46,15 @@ | ||
var dec = new SecureStreams.Decrypter({key: private_key}); | ||
var dec = new SecureStreams.Decrypter({private_key: private_key}); | ||
process.stdin.pipe(dec).pipe(process.stdout); | ||
or, to use a public key for decryption: | ||
var SecureStreams = require('node-secure-stream'); | ||
var fs = require('fs'); | ||
var public_key = fs.readFileSync(__dirname + '/files/public'); | ||
var dec = new SecureStreams.Decrypter({public_key: public_key}); | ||
process.stdin.pipe(dec).pipe(process.stdout); | ||
## Data transmitted | ||
@@ -41,0 +61,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
49997
375
72
0