// RSA, a suite of routines for performing RSA public-key computations in // JavaScript. // // Requires BigInt.js and Barrett.js. // // Copyright 1998-2005 David Shapiro. // // You may use, re-use, abuse, copy, and modify this code to your liking, but // please keep this header. // // Thanks! // // Dave Shapiro // dave@ohdave.com function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { this.e = biFromHex(encryptionExponent); this.d = biFromHex(decryptionExponent); this.m = biFromHex(modulus); // We can do two bytes per digit, so // chunkSize = 2 * (number of digits in modulus - 1). // Since biHighIndex returns the high index, not the number of digits, 1 has // already been subtracted. //this.chunkSize = 2 * biHighIndex(this.m); ////////////////////////////////// TYF this.digitSize = 2 * biHighIndex(this.m) + 2; this.chunkSize = this.digitSize - 11; // maximum, anything lower is fine ////////////////////////////////// TYF this.radix = 16; this.barrett = new BarrettMu(this.m); } function twoDigit(n) { return (n < 10 ? "0" : "") + String(n); } function encryptedString(key, s) // Altered by Rob Saunders (rob@robsaunders.net). New routine pads the // string after it has been converted to an array. This fixes an // incompatibility with Flash MX's ActionScript. // Altered by Tang Yu Feng for interoperability with Microsoft's // RSACryptoServiceProvider implementation. { ////////////////////////////////// TYF if (key.chunkSize > key.digitSize - 11) { return "Error"; } ////////////////////////////////// TYF var a = new Array(); var sl = s.length; var i = 0; var j = 0; while (i < sl) { //a[i] = s.charCodeAt(i); var c = s.charCodeAt(i); if (c > 0x10000){ // 4 bytes a[j] = 0xF0 | ((c & 0x1C0000) >>> 18); j++; a[j] = 0x80 | ((c & 0x3F000) >>> 12); j++; a[j] = 0x80 | ((c & 0xFC0) >>> 6); j++; a[j] = 0x80 | (c & 0x3F); //j = j + 4; }else if (c > 0x800){ // 3 bytes a[j] = 0xE0 | ((c & 0xF000) >>> 12); j++; a[j] = 0x80 | ((c & 0xFC0) >>> 6); j++; a[j] = 0x80 | (c & 0x3F); j++; }else if (c > 0x80){ // 2 bytes a[j] = 0xC0 | ((c & 0x7C0) >>> 6); j++; a[j] = 0x80 | (c & 0x3F); j++; }else{ // 1 byte a[j] = c; j++; } i++; } //while (a.length % key.chunkSize != 0) { // a[i++] = 0; //} var al = a.length; var result = ""; var j, k, block; for (i = 0; i < al; i += key.chunkSize) { block = new BigInt(); j = 0; //for (k = i; k < i + key.chunkSize; ++j) { // block.digits[j] = a[k++]; // block.digits[j] += a[k++] << 8; //} ////////////////////////////////// TYF // Add PKCS#1 v1.5 padding // 0x00 || 0x02 || PseudoRandomNonZeroBytes || 0x00 || Message // Variable a before padding must be of at most digitSize-11 // That is for 3 marker bytes plus at least 8 random non-zero bytes var x; var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize; // Variable b with 0x00 || 0x02 at the highest index. var b = new Array(); for (x=0; x