File: libs/js/pidCrypt/javascripts/original scripts/rsa.js

Recommend this page to a friend!
  Classes of Jason Gerfen   jQuery.pidCrypt   libs/js/pidCrypt/javascripts/original scripts/rsa.js   Download  
File: libs/js/pidCrypt/javascripts/original scripts/rsa.js
Role: Class source
Content type: text/plain
Description: Class source
Class: jQuery.pidCrypt
Encrypt form values using RSA and AES
Author: By
Last change:
Date: 10 months ago
Size: 8,145 bytes
 

Contents

Class file image Download
// Depends on jsbn.js and rng.js // convert a (hex) string to a bignum object function parseBigInt(str,r) { return new BigInteger(str,r); } function linebrk(s,n) { var ret = ""; var i = 0; while(i + n < s.length) { ret += s.substring(i,i+n) + "\n"; i += n; } return ret + s.substring(i,s.length); } function byte2Hex(b) { if(b < 0x10) return "0" + b.toString(16); else return b.toString(16); } // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint function pkcs1pad2(s,n) { if(n < s.length + 11) { alert("Message too long for RSA"); return null; } var ba = new Array(); var i = s.length - 1; while(i >= 0 && n > 0) ba[--n] = s.charCodeAt(i--); ba[--n] = 0; var rng = new SecureRandom(); var x = new Array(); while(n > 2) { // random non-zero pad x[0] = 0; while(x[0] == 0) rng.nextBytes(x); ba[--n] = x[0]; } ba[--n] = 2; ba[--n] = 0; return new BigInteger(ba); } // "empty" RSA key constructor function RSAKey() { this.n = null; this.e = 0; this.d = null; this.p = null; this.q = null; this.dmp1 = null; this.dmq1 = null; this.coeff = null; } // Set the public key fields N and e from hex strings function RSASetPublic(N,E,radix) { if (typeof(radix) == 'undefined') radix = 16; if(N != null && E != null && N.length > 0 && E.length > 0) { this.n = parseBigInt(N,radix); this.e = parseInt(E,radix); } else alert("Invalid RSA public key"); } // Perform raw public operation on "x": return x^e (mod n) function RSADoPublic(x) { return x.modPowInt(this.e, this.n); } // Return the PKCS#1 RSA encryption of "text" as an even-length hex string 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; } // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string function RSAEncryptB64(text) { var h = this.encrypt(text); if(h) return hex2b64(h); else return null; } // protected RSAKey.prototype.doPublic = RSADoPublic; // public RSAKey.prototype.setPublic = RSASetPublic; RSAKey.prototype.encrypt = RSAEncrypt; //RSAKey.prototype.encrypt_b64 = RSAEncryptB64; // Depends on rsa.js and jsbn2.js // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext function pkcs1unpad2(d,n) { var b = d.toByteArray(); var i = 0; while(i < b.length && b[i] == 0) ++i; if(b.length-i != n-1 || b[i] != 2) return null; ++i; while(b[i] != 0) if(++i >= b.length) return null; var ret = ""; while(++i < b.length) ret += String.fromCharCode(b[i]); return ret; } // Set the private key fields N, e, and d from hex strings function RSASetPrivate(N,E,D,radix) { if (typeof(radix) == 'undefined') radix = 16; if(N != null && E != null && N.length > 0 && E.length > 0) { this.n = parseBigInt(N,radix); this.e = parseInt(E,radix); this.d = parseBigInt(D,radix); } else alert("Invalid RSA private key"); } // Set the private key fields N, e, d and CRT params from hex strings function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C,radix) { if (typeof(radix) == 'undefined') radix = 16; if(N != null && E != null && N.length > 0 && E.length > 0) { this.n = parseBigInt(N,radix); this.e = parseInt(E,radix); this.d = parseBigInt(D,radix); this.p = parseBigInt(P,radix); this.q = parseBigInt(Q,radix); this.dmp1 = parseBigInt(DP,radix); this.dmq1 = parseBigInt(DQ,radix); this.coeff = parseBigInt(C,radix); } else alert("Invalid RSA private key"); } // Generate a new random private key B bits long, using public expt E function RSAGenerate(B,E) { var rng = new SecureRandom(); var qs = B>>1; this.e = parseInt(E,16); var ee = new BigInteger(E,16); for(;;) { for(;;) { this.p = new BigInteger(B-qs,1,rng); if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break; } for(;;) { this.q = new BigInteger(qs,1,rng); if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break; } if(this.p.compareTo(this.q) <= 0) { var t = this.p; this.p = this.q; this.q = t; } var p1 = this.p.subtract(BigInteger.ONE); var q1 = this.q.subtract(BigInteger.ONE); var phi = p1.multiply(q1); if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { this.n = this.p.multiply(this.q); this.d = ee.modInverse(phi); this.dmp1 = this.d.mod(p1); this.dmq1 = this.d.mod(q1); this.coeff = this.q.modInverse(this.p); break; } } } // Perform raw private operation on "x": return x^d (mod n) function RSADoPrivate(x) { if(this.p == null || this.q == null) return x.modPow(this.d, this.n); // TODO: re-calculate any missing CRT params var xp = x.mod(this.p).modPow(this.dmp1, this.p); var xq = x.mod(this.q).modPow(this.dmq1, this.q); while(xp.compareTo(xq) < 0) xp = xp.add(this.p); return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); } // Return the PKCS#1 RSA decryption of "ctext". // "ctext" is an even-length hex string and the output is a plain string. function RSADecrypt(ctext) { var c = parseBigInt(ctext, 16); alert(ctext); var m = this.doPrivate(c); if(m == null) return null; return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); } // Return the PKCS#1 RSA decryption of "ctext". // "ctext" is a Base64-encoded string and the output is a plain string. //function RSAB64Decrypt(ctext) { // var h = b64tohex(ctext); // if(h) return this.decrypt(h); else return null; //} // protected RSAKey.prototype.doPrivate = RSADoPrivate; // public RSAKey.prototype.setPrivate = RSASetPrivate; RSAKey.prototype.setPrivateEx = RSASetPrivateEx; RSAKey.prototype.generate = RSAGenerate; RSAKey.prototype.decrypt = RSADecrypt; RSAKey.prototype.b64_encrypt = RSAEncryptB64; //RSAKey.prototype.b64_decrypt = RSAB64Decrypt; RSAKey.prototype.getASNData = function(tree) { var params = {}; var data = []; var p=0; if(tree.value) data[p++] = tree.value; if(tree.sub) for(var i=0;i<tree.sub.length;i++) data = data.concat(this.getASNData(tree.sub[i])); return data; } // // //get parameters from ASN1 structure object e.g. created from pidCrypt.ASN1 //e.g. RSA Public Key // { // SEQUENCE: // { // INTEGER: modulus, // INTEGER: public exponent // } //} RSAKey.prototype.setKeyFromASN = function(key,asntree) { var keys = ['N','E','D','P','Q','DP','DQ','C']; var params = {}; var asnData = this.getASNData(asntree); switch(key){ case 'Public': case 'public': for(var i=0;i<asnData.length;i++) params[keys[i]] = asnData[i].toLowerCase(); this.setPublic(params.N,params.E,16); break; case 'Private': case 'private': for(var i=1;i<asnData.length;i++) params[keys[i-1]] = asnData[i].toLowerCase(); this.setPrivateEx(params.N,params.E,params.D,params.P,params.Q,params.DP,params.DQ,params.C,16); // this.setPrivate(params.N,params.E,params.D); break; } } RSAKey.prototype.setPublicKeyFromASN = function(asntree) { this.setKeyFromASN('public',asntree); } RSAKey.prototype.setPrivateKeyFromASN = function(asntree) { this.setKeyFromASN('private',asntree); }