horbert

RSA encryption & decryption

Jul 17th, 2013
822
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var RSA = {
  2.     getPublicKey: function($pem) {
  3.         if ($pem.length < 50)
  4.             return false;
  5.         if ($pem.substr(0, 26) != "-----BEGIN PUBLIC KEY-----")
  6.             return false;
  7.         $pem = $pem.substr(26);
  8.         if ($pem.substr($pem.length - 24) != "-----END PUBLIC KEY-----")
  9.             return false;
  10.         $pem = $pem.substr(0, $pem.length - 24);
  11.         $pem = new ASN1Data(Base64.decode($pem));
  12.         if ($pem.error)
  13.             return false;
  14.         $pem = $pem.data;
  15.         if ($pem[0][0][0] == "1.2.840.113549.1.1.1")
  16.             return new RSAPublicKey($pem[0][1][0][0], $pem[0][1][0][1]);
  17.         return false;
  18.     },
  19.     encrypt: function($data, $pubkey) {
  20.         if (!$pubkey)
  21.             return false;
  22.         var bytes = ($pubkey.modulus.bitLength() + 7) >> 3;
  23.         $data = this.pkcs1pad2($data, bytes);
  24.         if (!$data)
  25.             return false;
  26.         $data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus);
  27.         if (!$data)
  28.             return false;
  29.         $data = $data.toString(16);
  30.         while ($data.length < bytes * 2)
  31.             $data = '0' + $data;
  32.         return Base64.encode(Hex.decode($data));
  33.     },
  34.     decrypt: function($text, $pubkey)
  35.     {
  36.         if (!$pubkey)
  37.             return false;
  38.         $text = Hex.encode(Base64.decode($text)).toString(16);
  39.         while ($text[0] == '0')
  40.             $text = $text.replace('0', '');
  41.         $text = new BigInteger($text, 16);
  42.         $text = $text.modPowInt($pubkey.encryptionExponent, $pubkey.modulus);
  43.         if (!$text)
  44.             return false;
  45.         var bytes = ($pubkey.modulus.bitLength() + 7) >> 3;
  46.         $text = this.pkcs1unpad2($text, bytes);
  47.  
  48.         return $text;
  49.     },
  50.     pkcs1pad2: function pkcs1pad2(s, n) {
  51.         if (n < s.length + 11) { // TODO: fix for utf-8
  52.             alert("Message too long for RSA");
  53.             return null;
  54.         }
  55.         var ba = new Array();
  56.         var i = s.length - 1;
  57.         while (i >= 0 && n > 0) {
  58.             var c = s.charCodeAt(i--);
  59.             if (c < 128) { // encode using utf-8
  60.                 ba[--n] = c;
  61.             }
  62.             else if ((c > 127) && (c < 2048)) {
  63.                 ba[--n] = (c & 63) | 128;
  64.                 ba[--n] = (c >> 6) | 192;
  65.             }
  66.             else {
  67.                 ba[--n] = (c & 63) | 128;
  68.                 ba[--n] = ((c >> 6) & 63) | 128;
  69.                 ba[--n] = (c >> 12) | 224;
  70.             }
  71.         }
  72.         ba[--n] = 0;
  73.         var rng = new SecureRandom();
  74.         var x = new Array();
  75.         while (n > 2) { // random non-zero pad
  76.             x[0] = 0;
  77.             while (x[0] == 0)
  78.                 rng.nextBytes(x);
  79.             ba[--n] = x[0];
  80.         }
  81.         ba[--n] = 2;
  82.         ba[--n] = 0;
  83.         return new BigInteger(ba);
  84.     },
  85.     pkcs1unpad2: function pkcs1unpad2(d, n)
  86.     {
  87.         var b = d.toByteArray();
  88.         var i = 0;
  89.         while (i < b.length && b[i] == 0)
  90.             ++i;
  91.         /*if (b.length - i != n - 1 || b[i] != 2)
  92.          return null;*/
  93.         ++i;
  94.         while (b[i] != 0)
  95.             if (++i >= b.length)
  96.                 return null;
  97.         var ret = "";
  98.         while (++i < b.length) {
  99.             var c = b[i] & 255;
  100.             if (c < 128) { // utf-8 decode
  101.                 ret += String.fromCharCode(c);
  102.             }
  103.             else if ((c > 191) && (c < 224)) {
  104.                 ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
  105.                 ++i;
  106.             }
  107.             else {
  108.                 ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
  109.                 i += 2;
  110.             }
  111.         }
  112.         return ret;
  113.     }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment