travist / jsencrypt

A zero-dependency Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
http://www.travistidwell.com/jsencrypt
Other
6.68k stars 2.02k forks source link

Rhino support? #21

Closed tiny-tinker closed 10 years ago

tiny-tinker commented 10 years ago

Hello! This is an awesome utility and I appreciate the work you've done to convert the work of Tom Wu. I am looking to do some decrypting with an application that uses the rhino javascript engine, however, when I try to load this jsencrypt.js file, I get a few errors related to window and navigator:

[user@host ~]$ which rhino
/usr/bin/rhino
[user@host ~]$ rhino
Rhino 1.7 release 0.7.r2.2.9.amzn1 2012 03 08
js> load( 'https://raw.github.com/travist/jsencrypt/5ce6c71731b1622983bfddcc499cdd80702ca88c/bin/jsencrypt.js' );
js: "https://raw.github.com/travist/jsencrypt/5ce6c71731b1622983bfddcc499cdd80702ca88c/bin/jsencrypt.js", line 72: uncaught JavaScript runtime exception: ReferenceError: "navigator" is not defined.
        at https://raw.github.com/travist/jsencrypt/5ce6c71731b1622983bfddcc499cdd80702ca88c/bin/jsencrypt.js:72
        at https://raw.github.com/travist/jsencrypt/5ce6c71731b1622983bfddcc499cdd80702ca88c/bin/jsencrypt.js:2
        at <stdin>:2

js>

I poked through and tried setting navigator = {} on line 73 and got an error about window, so I did the same for window = {} on 1276, but ran into another error about ASN1. Suggestions or ideas?

Thanks again!

tiny-tinker commented 10 years ago

Oh, well I think i got it working... haven't fully tested yet, but it successfully loads. I set

var window = {};
var navigator ={};

around line 73. Then, it looks like the "ASN1.prototype.getHexStringValue" around line 3834 is outside the anonymous function its brothers are in. So, I move the closing }) (); to just after this block.

tiny-tinker commented 10 years ago

Darn.. I can't just fake it :)

travist commented 10 years ago

We will need to patch the jsbn libraries from Tom Wu to fix this issue. It can probably be done if you just add a check if those variables exist before calling an object within them. Like this...

if(j_lm && navigator && (navigator.appName == "Microsoft Internet Explorer")) {
  BigInteger.prototype.am = am2;
  dbits = 30;
}
else if(j_lm && navigator && (navigator.appName != "Netscape")) {
  BigInteger.prototype.am = am1;
  dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
  BigInteger.prototype.am = am3;
  dbits = 28;
}
tiny-tinker commented 10 years ago

Hmmm, making those changes resulted in the not defined error:

ReferenceError: "window" is not defined.

So I just added some if statements: (~line 74)

if( typeof window === "undefined" )
  var window = {};
if( typeof navigator === "undefined" )
  var navigator = {}; 

if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
  BigInteger.prototype.am = am2;
  dbits = 30;
}
else if(j_lm && (navigator.appName != "Netscape")) {
  BigInteger.prototype.am = am1;
  dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
  BigInteger.prototype.am = am3;
  dbits = 28;
}

I had to make one more change as I was getting:

"../jsencrypt.js", line 3837: uncaught JavaScript runtime exception: ReferenceError: "ASN1" is not defined.

So I added "window" here: (~line 3837)

window.ASN1.prototype.getHexStringValue = function(){
    var hexString = this.toHexString();
    var offset = this.header * 2;
    var length = this.length * 2;
    return hexString.substr(offset,length);
};

This of course resulted in a few other errors. I added "window." to the Base64 and ASN1 objects below: (~line 3867)

RSAKey.prototype.parseKey = function(pem) {
    try{
        var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/;
        var der = reHex.test(pem) ? Hex.decode(pem) : window.Base64.unarmor(pem);
        var asn1 = window.ASN1.decode(der);

Finally, I ran this code before I did the load( 'jsencrypt' ) call:

console = { 
   error: function( stuff ) { print( stuff ) },
   warn:  function( stuff ) { print( stuff ) },
   info:  function( stuff ) { print( stuff ) },
   debug: function( stuff ) { print( stuff ) },
   log:   function( stuff ) { print( stuff ) }
}

I haven't tried decrypting yet, the thread keeps running out of memory. I'm pretty sure there is a meomory leak in rhino or something. I'll have to dig into that.

zoloft commented 10 years ago

Hey @nomadic-squirrel

MadBookPro:~ zoloft$ rhino -opt -1
Rhino 1.7 release 4 2012 06 18
js> load('http://www.envjs.com/dist/env.rhino.1.2.js');
[  Envjs/1.6 (Rhino; U; Mac OS X x86_64 10.9.3; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
js> load('https://raw.githubusercontent.com/travist/jsencrypt/master/bin/jsencrypt.js');
js> 

I have not tried yet to encrypt/decrypt but my guess is that is working. Please tell me if it does, so that we can close this issue

zoloft commented 10 years ago
Rhino 1.7 release 4 2012 06 18
js> load('http://www.envjs.com/dist/env.rhino.1.2.js');
[  Envjs/1.6 (Rhino; U; Mac OS X x86_64 10.9.3; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
js> load('https://raw.githubusercontent.com/travist/jsencrypt/master/bin/jsencrypt.js');
js> var encrypt = new JSEncrypt({default_key_size:512});
js> encrypt.getKey();
[object Object]
js> console.log(encrypt.getPrivateKey());
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAIffqt9plHVSYV1r+9R2F/dGwPdkJESOrG+uhgqDeabFVwcFN3SE
QQtBIs5swz9SV+GsltrKunbnTUot+huwUeUCAwEAAQJAJH/UAgH1rHJ9zz/DvXYf
yABMs+hFydjdv36NaWOaGU9AZn8EUQAhHguxGTzcfBTNAfmHfkTXp/EcUmMHn6FE
wQIhAO6viXs1YUmU3N3XRPsXtFA9uzw06BUGQ1x4iTLvg1AxAiEAkbrhuxy19pKp
rEwQEal3mIiNvT24kJOK/51ghVlUA/UCIQC3HMgWU99tOd0v/ASZtZfJr3JDQDuE
Vae7+2UWRJWzIQIgIbwUMx9jVBABbRwygBQt1kaOISefiQBOpfuFc3kJRN0CIGfO
Wa1wi9DmPB0QGQ24Y/+eW4Eb3YRfEwYo+D/BUXuW
-----END RSA PRIVATE KEY-----
js> 

Seems to work, closing this issue

tiny-tinker commented 10 years ago

Hey, sorry, this was on my list to checkout, but I haven't gotten to it yet. If I get a chance, I'll check it out, but I'm fine with closing this issue. Thanks!!