javascriptencryptionrsajsbn

Choosing N and E for Javascript RSA Key Generation using JSBN


I'm using the JSBN library found at http://www-cs-students.stanford.edu/~tjw/jsbn/. I'm particularly trying to make the RSASetPublic() call in rsa.js, like this:

publicPem = RSASetPublic(N,E);

For example, when N = "667" and E = "327" I get the alert "Message too long for RSA".

The function is

function RSASetPublic(N,E) {
  if(N != null && E != null && N.length > 0 && E.length > 0) {
    this.n = parseBigInt(N,16);
    this.e = parseInt(E,16);
  }
  else
    alert("Invalid RSA public key");
}

which calls other functions...

function parseBigInt(str,r) {
  return new BigInteger(str,r);
}

function BigInteger(a,b,c) {
  if(a != null)
    if("number" == typeof a) this.fromNumber(a,b,c);
    else if(b == null && "string" != typeof a) this.fromString(a,256);
    else this.fromString(a,b);
}

And the BigInteger fromString() function is...

function bnpFromString(s,b) {
  var k;
  if(b == 16) k = 4;
  else if(b == 8) k = 3;
  else if(b == 256) k = 8; // byte array
  else if(b == 2) k = 1;
  else if(b == 32) k = 5;
  else if(b == 4) k = 2;
  else { this.fromRadix(s,b); return; }
  this.t = 0;
  this.s = 0;
  ....

And then, to use the key that was generated, such as with RSAEncrypt(text), n is important when the text is padded and encrypted...

function RSAEncrypt(text) {
  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
  if(m == null) return null;
  var c = this.doPublic(m);
  if(c == null) return null;
  var h = c.toString(16);
  if((h.length & 1) == 0) return h; else return "0" + h;
}

function pkcs1pad2(s,n) {
  if(n < s.length + 11) { // TODO: fix for utf-8
    alert("Message too long for RSA");
    return null;
  }
  var ba = new Array();
  var i = s.length - 1;
  while(i >= 0 && n > 0) {
     var c = s.charCodeAt(i--);
     if(c < 128) { // encode using utf-8
        ba[--n] = c;
     }
     ....

So I've gathered from various sources the following advice:

Sites like http://asecuritysite.com/encryption/rsa are helpful for high-level understanding of the algorithm but I still don't know how his translates to specific parameter assignments, or what N and E (versus n and e) explicitely mean. So what should N and E be? How do I choose so the message is not "too long for RSA"?


Solution

  • Since it's hard to find a 1024-bit number that is the product of two large primes p and q, the solutions I found were:

    1. to download openssl, launch the .exe found in bin, and generate an N value using:

      $openssl genrsa -out privatekey.txt 1024

      $openssl cat privatekey.txt

    2. to use the jsbn2.js function RSAGenerate(B,E) passing in B=1024 and E=your public exponent, probably "10001" (base16), so that the modulus is generated for you.

    I also noted that jsbn likes its inputs in hex, not decimal, and then converts them to the BigInteger type.