JSCryptor icon indicating copy to clipboard operation
JSCryptor copied to clipboard

npm install jscryptor fails on Mojave

Open Dirk- opened this issue 6 years ago • 10 comments

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- avatar Jul 08 '19 14:07 Dirk-

@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 avatar Jul 08 '19 19:07 chesstrian

@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.

Dirk- avatar Jul 09 '19 07:07 Dirk-

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 avatar Jul 09 '19 19:07 chesstrian

@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.

Dirk- avatar Jul 10 '19 08:07 Dirk-

@chesstrian cryptian now compiles fine, the author made some changes to the native abstraction layer.

Dirk- avatar Jul 15 '19 08:07 Dirk-

Hi @Dirk-, I know you are needing this, please give a couple of days I will dedicate some time to this.

chesstrian avatar Jul 16 '19 12:07 chesstrian

@chesstrian Thanks, no need to hurry, take your time. You don't owe me anything. :)

Dirk- avatar Jul 16 '19 13:07 Dirk-

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;
})();

peerobo avatar Dec 10 '19 17:12 peerobo

Thanks @peerobo, feel free to make a PR.

chesstrian avatar Dec 10 '19 17:12 chesstrian

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?

b00tsy avatar Aug 02 '21 06:08 b00tsy