npm install jscryptor fails on Mojave
I tried to install JSCryptor on macOS 10.14.5 with an up-to-date version of brew and npm installed. brew install libmcrypt works, but npm install jscryptor fails.
I'd like to use JSCryptor as I am also using RNCryptor with native iOS and macOS apps and want to add a cross-platform app.
Below you see the complete output of the npm command. Any advice?
Thanks a lot, Dirk
MacBook-Pro:~ user$ npm install jscryptor
> [email protected] install /Users/user/node_modules/mcrypt
> node-gyp rebuild
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/3-way.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/arcfour.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/blowfish.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/blowfish-compat.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/cast-128.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/cast-256.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/des.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/enigma.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/gost.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/loki97.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/panama.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/rc2.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/rijndael-128.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/rijndael-192.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/rijndael-256.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/safer64.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/safer128.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/saferplus.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/serpent.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/tripledes.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/twofish.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/wake.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/algorithms/xtea.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/cbc.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/cfb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/ctr.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/ecb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/ncfb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/nofb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/ofb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/modules/modes/stream.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/bzero.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/mcrypt.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/mcrypt_extra.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/mcrypt_modules.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/mcrypt_symb.o
CC(target) Release/obj.target/libmcrypt/lib/libmcrypt/lib/xmemory.o
LIBTOOL-STATIC Release/mcrypt.a
CXX(target) Release/obj.target/mcrypt/src/mcrypt.o
In file included from ../src/mcrypt.cc:3:
../src/mcrypt.h:21:26: error: no template named 'Handle'
static void Init(Handle<Object> exports);
^
../src/mcrypt.cc:294:37: error: no matching member function for call to 'ToBoolean'
Local<Boolean> state = info[0]->ToBoolean();
~~~~~~~~~^~~~~~~~~
/Users/dirk/.node-gyp/12.5.0/include/node/v8.h:2524:59: note: candidate function not viable: requires single argument 'context',
but no arguments were provided
V8_WARN_UNUSED_RESULT MaybeLocal<Boolean> ToBoolean(
^
/Users/dirk/.node-gyp/12.5.0/include/node/v8.h:2540:18: note: candidate function not viable: requires single argument 'isolate',
but no arguments were provided
Local<Boolean> ToBoolean(Isolate* isolate) const;
^
../src/mcrypt.cc:307:37: error: no matching member function for call to 'ToBoolean'
Local<Boolean> state = info[0]->ToBoolean();
~~~~~~~~~^~~~~~~~~
/Users/user/.node-gyp/12.5.0/include/node/v8.h:2524:59: note: candidate function not viable: requires single argument 'context',
but no arguments were provided
V8_WARN_UNUSED_RESULT MaybeLocal<Boolean> ToBoolean(
^
/Users/user/.node-gyp/12.5.0/include/node/v8.h:2540:18: note: candidate function not viable: requires single argument 'isolate',
but no arguments were provided
Local<Boolean> ToBoolean(Isolate* isolate) const;
^
../src/mcrypt.cc:398:16: warning: 'Set' is deprecated: Use maybe version [-Wdeprecated-declarations]
array->Set(i, Nan::New<Number>(keySizes[i]));
^
/Users/user/.node-gyp/12.5.0/include/node/v8.h:3367:3: note: 'Set' has been explicitly marked deprecated here
V8_DEPRECATE_SOON("Use maybe version",
^
/Users/user/.node-gyp/12.5.0/include/node/v8config.h:326:29: note: expanded from macro 'V8_DEPRECATE_SOON'
declarator __attribute__((deprecated(message)))
^
../src/mcrypt.cc:476:16: warning: 'Set' is deprecated: Use maybe version [-Wdeprecated-declarations]
array->Set(i, Nan::New<String>(algos[i]).ToLocalChecked());
^
/Users/user/.node-gyp/12.5.0/include/node/v8.h:3367:3: note: 'Set' has been explicitly marked deprecated here
V8_DEPRECATE_SOON("Use maybe version",
^
/Users/user/.node-gyp/12.5.0/include/node/v8config.h:326:29: note: expanded from macro 'V8_DEPRECATE_SOON'
declarator __attribute__((deprecated(message)))
^
../src/mcrypt.cc:495:16: warning: 'Set' is deprecated: Use maybe version [-Wdeprecated-declarations]
array->Set(i, Nan::New<String>(modes[i]).ToLocalChecked());
^
/Users/user/.node-gyp/12.5.0/include/node/v8.h:3367:3: note: 'Set' has been explicitly marked deprecated here
V8_DEPRECATE_SOON("Use maybe version",
^
/Users/user/.node-gyp/12.5.0/include/node/v8config.h:326:29: note: expanded from macro 'V8_DEPRECATE_SOON'
declarator __attribute__((deprecated(message)))
^
../src/mcrypt.cc:503:14: error: variable has incomplete type 'void'
void MCrypt::Init(Handle<Object> exports) {
^
../src/mcrypt.cc:503:26: error: 'Object' does not refer to a value
void MCrypt::Init(Handle<Object> exports) {
^
/Users/user/.node-gyp/12.5.0/include/node/v8.h:3356:17: note: declared here
class V8_EXPORT Object : public Value {
^
../src/mcrypt.cc:503:19: error: use of undeclared identifier 'Handle'
void MCrypt::Init(Handle<Object> exports) {
^
../src/mcrypt.cc:503:34: error: use of undeclared identifier 'exports'
void MCrypt::Init(Handle<Object> exports) {
^
../src/mcrypt.cc:503:42: error: expected ';' after top level declarator
void MCrypt::Init(Handle<Object> exports) {
^
;
3 warnings and 8 errors generated.
make: *** [Release/obj.target/mcrypt/src/mcrypt.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack at ChildProcess.emit (events.js:200:13)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Darwin 18.6.0
gyp ERR! command "/usr/local/Cellar/node/12.5.0/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/user/node_modules/mcrypt
gyp ERR! node -v v12.5.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN enoent ENOENT: no such file or directory, open '/Users/dirk/package.json'
npm WARN user No description
npm WARN user No repository field.
npm WARN user No README data
npm WARN user No license field.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/user/.npm/_logs/2019-07-08T13_47_45_468Z-debug.log
MacBook-Pro:~ user$
@Dirk- Unfortunately jscriptor depends on mcrypt which is currently working in Node 8, then jscryptor works on Node 8 at most. I recommend to report this issue in mcrypt repo.
@chesstrian Thanks for the quick reply. The mcrypt repo is "not in active maintain state". It recommends to use the cryptian lib. I'll see what I can accomplish with this library.
I see this new library is failing with the same problem, however it replaces mcrypt, will keep an eye on this in order to update jscryptor.
Perhaps it worth writing jscryptor in C, so we have no dependencies. @Dirk- thoughts?
@chesstrian Well, I am a complete JavaScript noop, so I have no idea where the interface between C and JavaScript would be and how much effort would be needed. But the errors I ran into with jscryptor and cryptian seem to be very similar and focused, so maybe they could be fixed with some compiler directives or simple changes.
@chesstrian cryptian now compiles fine, the author made some changes to the native abstraction layer.
Hi @Dirk-, I know you are needing this, please give a couple of days I will dedicate some time to this.
@chesstrian Thanks, no need to hurry, take your time. You don't owe me anything. :)
For anyone having error when running with node v12: (I use Cryptian instead of MCrypt) Bumping @Dirk- @chesstrian
(function() {
const crypto = require('crypto');
const {algorithm, mode} = require('cryptian');
...
var _generate_iv = function (block_size) {
var arr = [];
for (var i = 0; i < block_size; i++) {
arr[i] = 255 * Math.random();
}
var iv = Buffer.from(arr);
return iv;
};
...
var _encrypt = function(plain_text, components, encryption_key, hmac_key) {
var padded_plain_text = _add_pkcs7_padding(plain_text, components.headers.iv.length);
const iv = components.headers.iv;
const dummy = new algorithm.Rijndael128();
dummy.setKey(encryption_key);
const cipher = new mode.cbc.Cipher(dummy, iv);
components.cipher_text = cipher.transform(padded_plain_text);
var data = Buffer.concat([
components.headers.version,
components.headers.options,
components.headers.encryption_salt || Buffer.from(''),
components.headers.hmac_salt || Buffer.from(''),
components.headers.iv,
components.cipher_text
]);
var hmac = _generate_hmac(components, hmac_key);
return Buffer.concat([data, hmac]).toString('base64');
};
...
RNCryptor.Decrypt = function(b64str, password) {
var components = _unpack_encrypted_base64_data(b64str);
Buffer.isBuffer(password) || (password = Buffer.from(password, 'binary'));
if (!_hmac_is_valid(components, password)) {
return;
}
var key = _generate_key(password, components.headers.encryption_salt);
const iv = components.headers.iv;
const dummy = new algorithm.Rijndael128();
dummy.setKey(key);
const cipher = new mode.cbc.Decipher(dummy, iv);
var padded_plain_text = cipher.transform(components.cipher_text);
return _strip_pkcs7_padding(padded_plain_text);
};
module.exports = RNCryptor;
})();
Thanks @peerobo, feel free to make a PR.
The native node crypto module got quite powerful in recent releases, meaning no dependencies at all would be required anymore. However, it would break support for previous node versions (probably < 10 or < 12).
There's another library doing that already node-rncryptor: https://github.com/lucasfontesgaspareto/node-rncryptor, unfortunately, not production ready, yet. Maybe a joint effort to revive jscryptor for latest node versions?