RSA(非对称加密算法、公钥加密算法)

1.RSA

  1 // RSA, a suite of routines for performing RSA public-key computations in
  2 // JavaScript.
  3 //
  4 // Requires BigInt.js and Barrett.js.
  5 //
  6 // Copyright 1998-2005 David Shapiro.
  7 //
  8 // You may use, re-use, abuse, copy, and modify this code to your liking, but
  9 // please keep this header.
 10 //
 11 // Thanks!
 12 // 
 13 // Dave Shapiro
 14 // dave@ohdave.com 
 15 
 16 function RSAKeyPair(encryptionExponent, decryptionExponent, modulus)
 17 {
 18     this.e = biFromHex(encryptionExponent);
 19     this.d = biFromHex(decryptionExponent);
 20     this.m = biFromHex(modulus);
 21     
 22     // We can do two bytes per digit, so
 23     // chunkSize = 2 * (number of digits in modulus - 1).
 24     // Since biHighIndex returns the high index, not the number of digits, 1 has
 25     // already been subtracted.
 26     //this.chunkSize = 2 * biHighIndex(this.m);
 27     
 28     ////////////////////////////////// TYF
 29         this.digitSize = 2 * biHighIndex(this.m) + 2;
 30     this.chunkSize = this.digitSize - 11; // maximum, anything lower is fine
 31     ////////////////////////////////// TYF
 32 
 33     this.radix = 16;
 34     this.barrett = new BarrettMu(this.m);
 35 }
 36 
 37 function twoDigit(n)
 38 {
 39     return (n < 10 ? "0" : "") + String(n);
 40 }
 41 
 42 function encryptedString(key, s)
 43 // Altered by Rob Saunders (rob@robsaunders.net). New routine pads the
 44 // string after it has been converted to an array. This fixes an
 45 // incompatibility with Flash MX's ActionScript.
 46 // Altered by Tang Yu Feng for interoperability with Microsoft's
 47 // RSACryptoServiceProvider implementation.
 48 {
 49     ////////////////////////////////// TYF
 50     if (key.chunkSize > key.digitSize - 11)
 51     {
 52         return "Error";
 53     }
 54     ////////////////////////////////// TYF
 55 
 56 
 57     var a = new Array();
 58     var sl = s.length;
 59     
 60     var i = 0;
 61     while (i < sl) {
 62         a[i] = s.charCodeAt(i);
 63         i++;
 64     }
 65 
 66     //while (a.length % key.chunkSize != 0) {
 67     //    a[i++] = 0;
 68     //}
 69 
 70     var al = a.length;
 71     var result = "";
 72     var j, k, block;
 73     for (i = 0; i < al; i += key.chunkSize) {
 74         block = new BigInt();
 75         j = 0;
 76         
 77         //for (k = i; k < i + key.chunkSize; ++j) {
 78         //    block.digits[j] = a[k++];
 79         //    block.digits[j] += a[k++] << 8;
 80         //}
 81         
 82         ////////////////////////////////// TYF
 83         // Add PKCS#1 v1.5 padding
 84         // 0x00 || 0x02 || PseudoRandomNonZeroBytes || 0x00 || Message
 85         // Variable a before padding must be of at most digitSize-11
 86         // That is for 3 marker bytes plus at least 8 random non-zero bytes
 87         var x;
 88         var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize;
 89         
 90         // Variable b with 0x00 || 0x02 at the highest index.
 91         var b = new Array();
 92         for (x=0; x<msgLength; x++)
 93         {
 94             b[x] = a[i+msgLength-1-x];
 95         }
 96         b[msgLength] = 0; // marker
 97         var paddedSize = Math.max(8, key.digitSize - 3 - msgLength);
 98     
 99         for (x=0; x<paddedSize; x++) {
100             b[msgLength+1+x] = Math.floor(Math.random()*254) + 1; // [1,255]
101         }
102         // It can be asserted that msgLength+paddedSize == key.digitSize-3
103         b[key.digitSize-2] = 2; // marker
104         b[key.digitSize-1] = 0; // marker
105         
106         for (k = 0; k < key.digitSize; ++j) 
107         {
108             block.digits[j] = b[k++];
109             block.digits[j] += b[k++] << 8;
110         }
111         ////////////////////////////////// TYF
112 
113         var crypt = key.barrett.powMod(block, key.e);
114         var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix);
115         result += text + " ";
116     }
117     return result.substring(0, result.length - 1); // Remove last space.
118 }
119 
120 function decryptedString(key, s)
121 {
122     var blocks = s.split(" ");
123     var result = "";
124     var i, j, block;
125     for (i = 0; i < blocks.length; ++i) {
126         var bi;
127         if (key.radix == 16) {
128             bi = biFromHex(blocks[i]);
129         }
130         else {
131             bi = biFromString(blocks[i], key.radix);
132         }
133         block = key.barrett.powMod(bi, key.d);
134         for (j = 0; j <= biHighIndex(block); ++j) {
135             result += String.fromCharCode(block.digits[j] & 255,
136                                           block.digits[j] >> 8);
137         }
138     }
139     // Remove trailing null, if any.
140     if (result.charCodeAt(result.length - 1) == 0) {
141         result = result.substring(0, result.length - 1);
142     }
143     return result;
144 }
View Code

2.BigInt

  1 // BigInt, a suite of routines for performing multiple-precision arithmetic in
  2 // JavaScript.
  3 //
  4 // Copyright 1998-2005 David Shapiro.
  5 //
  6 // You may use, re-use, abuse,
  7 // copy, and modify this code to your liking, but please keep this header.
  8 // Thanks!
  9 //
 10 // Dave Shapiro
 11 // dave@ohdave.com
 12 
 13 // IMPORTANT THING: Be sure to set maxDigits according to your precision
 14 // needs. Use the setMaxDigits() function to do this. See comments below.
 15 //
 16 // Tweaked by Ian Bunning
 17 // Alterations:
 18 // Fix bug in function biFromHex(s) to allow
 19 // parsing of strings of length != 0 (mod 4)
 20 
 21 // Changes made by Dave Shapiro as of 12/30/2004:
 22 //
 23 // The BigInt() constructor doesn't take a string anymore. If you want to
 24 // create a BigInt from a string, use biFromDecimal() for base-10
 25 // representations, biFromHex() for base-16 representations, or
 26 // biFromString() for base-2-to-36 representations.
 27 //
 28 // biFromArray() has been removed. Use biCopy() instead, passing a BigInt
 29 // instead of an array.
 30 //
 31 // The BigInt() constructor now only constructs a zeroed-out array.
 32 // Alternatively, if you pass <true>, it won't construct any array. See the
 33 // biCopy() method for an example of this.
 34 //
 35 // Be sure to set maxDigits depending on your precision needs. The default
 36 // zeroed-out array ZERO_ARRAY is constructed inside the setMaxDigits()
 37 // function. So use this function to set the variable. DON'T JUST SET THE
 38 // VALUE. USE THE FUNCTION.
 39 //
 40 // ZERO_ARRAY exists to hopefully speed up construction of BigInts(). By
 41 // precalculating the zero array, we can just use slice(0) to make copies of
 42 // it. Presumably this calls faster native code, as opposed to setting the
 43 // elements one at a time. I have not done any timing tests to verify this
 44 // claim.
 45 
 46 // Max number = 10^16 - 2 = 9999999999999998;
 47 //               2^53     = 9007199254740992;
 48 
 49 var biRadixBase = 2;
 50 var biRadixBits = 16;
 51 var bitsPerDigit = biRadixBits;
 52 var biRadix = 1 << 16; // = 2^16 = 65536
 53 var biHalfRadix = biRadix >>> 1;
 54 var biRadixSquared = biRadix * biRadix;
 55 var maxDigitVal = biRadix - 1;
 56 var maxInteger = 9999999999999998; 
 57 
 58 // maxDigits:
 59 // Change this to accommodate your largest number size. Use setMaxDigits()
 60 // to change it!
 61 //
 62 // In general, if you're working with numbers of size N bits, you'll need 2*N
 63 // bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
 64 //
 65 // 1024 * 2 / 16 = 128 digits of storage.
 66 //
 67 
 68 var maxDigits;
 69 var ZERO_ARRAY;
 70 var bigZero, bigOne;
 71 
 72 function setMaxDigits(value)
 73 {
 74     maxDigits = value;
 75     ZERO_ARRAY = new Array(maxDigits);
 76     for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
 77     bigZero = new BigInt();
 78     bigOne = new BigInt();
 79     bigOne.digits[0] = 1;
 80 }
 81 
 82 setMaxDigits(20);
 83 
 84 // The maximum number of digits in base 10 you can convert to an
 85 // integer without JavaScript throwing up on you.
 86 var dpl10 = 15;
 87 // lr10 = 10 ^ dpl10
 88 var lr10 = biFromNumber(1000000000000000);
 89 
 90 function BigInt(flag)
 91 {
 92     if (typeof flag == "boolean" && flag == true) {
 93         this.digits = null;
 94     }
 95     else {
 96         this.digits = ZERO_ARRAY.slice(0);
 97     }
 98     this.isNeg = false;
 99 }
100 
101 function biFromDecimal(s)
102 {
103     var isNeg = s.charAt(0) == '-';
104     var i = isNeg ? 1 : 0;
105     var result;
106     // Skip leading zeros.
107     while (i < s.length && s.charAt(i) == '0') ++i;
108     if (i == s.length) {
109         result = new BigInt();
110     }
111     else {
112         var digitCount = s.length - i;
113         var fgl = digitCount % dpl10;
114         if (fgl == 0) fgl = dpl10;
115         result = biFromNumber(Number(s.substr(i, fgl)));
116         i += fgl;
117         while (i < s.length) {
118             result = biAdd(biMultiply(result, lr10),
119                            biFromNumber(Number(s.substr(i, dpl10))));
120             i += dpl10;
121         }
122         result.isNeg = isNeg;
123     }
124     return result;
125 }
126 
127 function biCopy(bi)
128 {
129     var result = new BigInt(true);
130     result.digits = bi.digits.slice(0);
131     result.isNeg = bi.isNeg;
132     return result;
133 }
134 
135 function biFromNumber(i)
136 {
137     var result = new BigInt();
138     result.isNeg = i < 0;
139     i = Math.abs(i);
140     var j = 0;
141     while (i > 0) {
142         result.digits[j++] = i & maxDigitVal;
143         i = Math.floor(i / biRadix);
144     }
145     return result;
146 }
147 
148 function reverseStr(s)
149 {
150     var result = "";
151     for (var i = s.length - 1; i > -1; --i) {
152         result += s.charAt(i);
153     }
154     return result;
155 }
156 
157 var hexatrigesimalToChar = new Array(
158  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
159  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
160  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
161  'u', 'v', 'w', 'x', 'y', 'z'
162 );
163 
164 function biToString(x, radix)
165     // 2 <= radix <= 36
166 {
167     var b = new BigInt();
168     b.digits[0] = radix;
169     var qr = biDivideModulo(x, b);
170     var result = hexatrigesimalToChar[qr[1].digits[0]];
171     while (biCompare(qr[0], bigZero) == 1) {
172         qr = biDivideModulo(qr[0], b);
173         digit = qr[1].digits[0];
174         result += hexatrigesimalToChar[qr[1].digits[0]];
175     }
176     return (x.isNeg ? "-" : "") + reverseStr(result);
177 }
178 
179 function biToDecimal(x)
180 {
181     var b = new BigInt();
182     b.digits[0] = 10;
183     var qr = biDivideModulo(x, b);
184     var result = String(qr[1].digits[0]);
185     while (biCompare(qr[0], bigZero) == 1) {
186         qr = biDivideModulo(qr[0], b);
187         result += String(qr[1].digits[0]);
188     }
189     return (x.isNeg ? "-" : "") + reverseStr(result);
190 }
191 
192 var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
193                           'a', 'b', 'c', 'd', 'e', 'f');
194 
195 function digitToHex(n)
196 {
197     var mask = 0xf;
198     var result = "";
199     for (i = 0; i < 4; ++i) {
200         result += hexToChar[n & mask];
201         n >>>= 4;
202     }
203     return reverseStr(result);
204 }
205 
206 function biToHex(x)
207 {
208     var result = "";
209     var n = biHighIndex(x);
210     for (var i = biHighIndex(x); i > -1; --i) {
211         result += digitToHex(x.digits[i]);
212     }
213     return result;
214 }
215 
216 function charToHex(c)
217 {
218     var ZERO = 48;
219     var NINE = ZERO + 9;
220     var littleA = 97;
221     var littleZ = littleA + 25;
222     var bigA = 65;
223     var bigZ = 65 + 25;
224     var result;
225 
226     if (c >= ZERO && c <= NINE) {
227         result = c - ZERO;
228     } else if (c >= bigA && c <= bigZ) {
229         result = 10 + c - bigA;
230     } else if (c >= littleA && c <= littleZ) {
231         result = 10 + c - littleA;
232     } else {
233         result = 0;
234     }
235     return result;
236 }
237 
238 function hexToDigit(s)
239 {
240     var result = 0;
241     var sl = Math.min(s.length, 4);
242     for (var i = 0; i < sl; ++i) {
243         result <<= 4;
244         result |= charToHex(s.charCodeAt(i))
245     }
246     return result;
247 }
248 
249 function biFromHex(s)
250 {
251     var result = new BigInt();
252     var sl = s.length;
253     for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
254         result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
255     }
256     return result;
257 }
258 
259 function biFromString(s, radix)
260 {
261     var isNeg = s.charAt(0) == '-';
262     var istop = isNeg ? 1 : 0;
263     var result = new BigInt();
264     var place = new BigInt();
265     place.digits[0] = 1; // radix^0
266     for (var i = s.length - 1; i >= istop; i--) {
267         var c = s.charCodeAt(i);
268         var digit = charToHex(c);
269         var biDigit = biMultiplyDigit(place, digit);
270         result = biAdd(result, biDigit);
271         place = biMultiplyDigit(place, radix);
272     }
273     result.isNeg = isNeg;
274     return result;
275 }
276 
277 function biDump(b)
278 {
279     return (b.isNeg ? "-" : "") + b.digits.join(" ");
280 }
281 
282 function biAdd(x, y)
283 {
284     var result;
285 
286     if (x.isNeg != y.isNeg) {
287         y.isNeg = !y.isNeg;
288         result = biSubtract(x, y);
289         y.isNeg = !y.isNeg;
290     }
291     else {
292         result = new BigInt();
293         var c = 0;
294         var n;
295         for (var i = 0; i < x.digits.length; ++i) {
296             n = x.digits[i] + y.digits[i] + c;
297             result.digits[i] = n % biRadix;
298             c = Number(n >= biRadix);
299         }
300         result.isNeg = x.isNeg;
301     }
302     return result;
303 }
304 
305 function biSubtract(x, y)
306 {
307     var result;
308     if (x.isNeg != y.isNeg) {
309         y.isNeg = !y.isNeg;
310         result = biAdd(x, y);
311         y.isNeg = !y.isNeg;
312     } else {
313         result = new BigInt();
314         var n, c;
315         c = 0;
316         for (var i = 0; i < x.digits.length; ++i) {
317             n = x.digits[i] - y.digits[i] + c;
318             result.digits[i] = n % biRadix;
319             // Stupid non-conforming modulus operation.
320             if (result.digits[i] < 0) result.digits[i] += biRadix;
321             c = 0 - Number(n < 0);
322         }
323         // Fix up the negative sign, if any.
324         if (c == -1) {
325             c = 0;
326             for (var i = 0; i < x.digits.length; ++i) {
327                 n = 0 - result.digits[i] + c;
328                 result.digits[i] = n % biRadix;
329                 // Stupid non-conforming modulus operation.
330                 if (result.digits[i] < 0) result.digits[i] += biRadix;
331                 c = 0 - Number(n < 0);
332             }
333             // Result is opposite sign of arguments.
334             result.isNeg = !x.isNeg;
335         } else {
336             // Result is same sign.
337             result.isNeg = x.isNeg;
338         }
339     }
340     return result;
341 }
342 
343 function biHighIndex(x)
344 {
345     var result = x.digits.length - 1;
346     while (result > 0 && x.digits[result] == 0) --result;
347     return result;
348 }
349 
350 function biNumBits(x)
351 {
352     var n = biHighIndex(x);
353     var d = x.digits[n];
354     var m = (n + 1) * bitsPerDigit;
355     var result;
356     for (result = m; result > m - bitsPerDigit; --result) {
357         if ((d & 0x8000) != 0) break;
358         d <<= 1;
359     }
360     return result;
361 }
362 
363 function biMultiply(x, y)
364 {
365     var result = new BigInt();
366     var c;
367     var n = biHighIndex(x);
368     var t = biHighIndex(y);
369     var u, uv, k;
370 
371     for (var i = 0; i <= t; ++i) {
372         c = 0;
373         k = i;
374         for (j = 0; j <= n; ++j, ++k) {
375             uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
376             result.digits[k] = uv & maxDigitVal;
377             c = uv >>> biRadixBits;
378             //c = Math.floor(uv / biRadix);
379         }
380         result.digits[i + n + 1] = c;
381     }
382     // Someone give me a logical xor, please.
383     result.isNeg = x.isNeg != y.isNeg;
384     return result;
385 }
386 
387 function biMultiplyDigit(x, y)
388 {
389     var n, c, uv;
390 
391     result = new BigInt();
392     n = biHighIndex(x);
393     c = 0;
394     for (var j = 0; j <= n; ++j) {
395         uv = result.digits[j] + x.digits[j] * y + c;
396         result.digits[j] = uv & maxDigitVal;
397         c = uv >>> biRadixBits;
398         //c = Math.floor(uv / biRadix);
399     }
400     result.digits[1 + n] = c;
401     return result;
402 }
403 
404 function arrayCopy(src, srcStart, dest, destStart, n)
405 {
406     var m = Math.min(srcStart + n, src.length);
407     for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
408         dest[j] = src[i];
409     }
410 }
411 
412 var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
413                              0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
414                              0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);
415 
416 function biShiftLeft(x, n)
417 {
418     var digitCount = Math.floor(n / bitsPerDigit);
419     var result = new BigInt();
420     arrayCopy(x.digits, 0, result.digits, digitCount,
421               result.digits.length - digitCount);
422     var bits = n % bitsPerDigit;
423     var rightBits = bitsPerDigit - bits;
424     for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
425         result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
426                            ((result.digits[i1] & highBitMasks[bits]) >>>
427                             (rightBits));
428     }
429     result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
430     result.isNeg = x.isNeg;
431     return result;
432 }
433 
434 var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
435                             0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
436                             0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);
437 
438 function biShiftRight(x, n)
439 {
440     var digitCount = Math.floor(n / bitsPerDigit);
441     var result = new BigInt();
442     arrayCopy(x.digits, digitCount, result.digits, 0,
443               x.digits.length - digitCount);
444     var bits = n % bitsPerDigit;
445     var leftBits = bitsPerDigit - bits;
446     for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
447         result.digits[i] = (result.digits[i] >>> bits) |
448                            ((result.digits[i1] & lowBitMasks[bits]) << leftBits);
449     }
450     result.digits[result.digits.length - 1] >>>= bits;
451     result.isNeg = x.isNeg;
452     return result;
453 }
454 
455 function biMultiplyByRadixPower(x, n)
456 {
457     var result = new BigInt();
458     arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
459     return result;
460 }
461 
462 function biDivideByRadixPower(x, n)
463 {
464     var result = new BigInt();
465     arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
466     return result;
467 }
468 
469 function biModuloByRadixPower(x, n)
470 {
471     var result = new BigInt();
472     arrayCopy(x.digits, 0, result.digits, 0, n);
473     return result;
474 }
475 
476 function biCompare(x, y)
477 {
478     if (x.isNeg != y.isNeg) {
479         return 1 - 2 * Number(x.isNeg);
480     }
481     for (var i = x.digits.length - 1; i >= 0; --i) {
482         if (x.digits[i] != y.digits[i]) {
483             if (x.isNeg) {
484                 return 1 - 2 * Number(x.digits[i] > y.digits[i]);
485             } else {
486                 return 1 - 2 * Number(x.digits[i] < y.digits[i]);
487             }
488         }
489     }
490     return 0;
491 }
492 
493 function biDivideModulo(x, y)
494 {
495     var nb = biNumBits(x);
496     var tb = biNumBits(y);
497     var origYIsNeg = y.isNeg;
498     var q, r;
499     if (nb < tb) {
500         // |x| < |y|
501         if (x.isNeg) {
502             q = biCopy(bigOne);
503             q.isNeg = !y.isNeg;
504             x.isNeg = false;
505             y.isNeg = false;
506             r = biSubtract(y, x);
507             // Restore signs, 'cause they're references.
508             x.isNeg = true;
509             y.isNeg = origYIsNeg;
510         } else {
511             q = new BigInt();
512             r = biCopy(x);
513         }
514         return new Array(q, r);
515     }
516 
517     q = new BigInt();
518     r = x;
519 
520     // Normalize Y.
521     var t = Math.ceil(tb / bitsPerDigit) - 1;
522     var lambda = 0;
523     while (y.digits[t] < biHalfRadix) {
524         y = biShiftLeft(y, 1);
525         ++lambda;
526         ++tb;
527         t = Math.ceil(tb / bitsPerDigit) - 1;
528     }
529     // Shift r over to keep the quotient constant. We'll shift the
530     // remainder back at the end.
531     r = biShiftLeft(r, lambda);
532     nb += lambda; // Update the bit count for x.
533     var n = Math.ceil(nb / bitsPerDigit) - 1;
534 
535     var b = biMultiplyByRadixPower(y, n - t);
536     while (biCompare(r, b) != -1) {
537         ++q.digits[n - t];
538         r = biSubtract(r, b);
539     }
540     for (var i = n; i > t; --i) {
541     var ri = (i >= r.digits.length) ? 0 : r.digits[i];
542     var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
543     var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
544     var yt = (t >= y.digits.length) ? 0 : y.digits[t];
545     var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
546         if (ri == yt) {
547             q.digits[i - t - 1] = maxDigitVal;
548         } else {
549             q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
550         }
551 
552         var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
553         var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
554         while (c1 > c2) {
555             --q.digits[i - t - 1];
556             c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
557             c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
558         }
559 
560         b = biMultiplyByRadixPower(y, i - t - 1);
561         r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
562         if (r.isNeg) {
563             r = biAdd(r, b);
564             --q.digits[i - t - 1];
565         }
566     }
567     r = biShiftRight(r, lambda);
568     // Fiddle with the signs and stuff to make sure that 0 <= r < y.
569     q.isNeg = x.isNeg != origYIsNeg;
570     if (x.isNeg) {
571         if (origYIsNeg) {
572             q = biAdd(q, bigOne);
573         } else {
574             q = biSubtract(q, bigOne);
575         }
576         y = biShiftRight(y, lambda);
577         r = biSubtract(y, r);
578     }
579     // Check for the unbelievably stupid degenerate case of r == -0.
580     if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;
581 
582     return new Array(q, r);
583 }
584 
585 function biDivide(x, y)
586 {
587     return biDivideModulo(x, y)[0];
588 }
589 
590 function biModulo(x, y)
591 {
592     return biDivideModulo(x, y)[1];
593 }
594 
595 function biMultiplyMod(x, y, m)
596 {
597     return biModulo(biMultiply(x, y), m);
598 }
599 
600 function biPow(x, y)
601 {
602     var result = bigOne;
603     var a = x;
604     while (true) {
605         if ((y & 1) != 0) result = biMultiply(result, a);
606         y >>= 1;
607         if (y == 0) break;
608         a = biMultiply(a, a);
609     }
610     return result;
611 }
612 
613 function biPowMod(x, y, m)
614 {
615     var result = bigOne;
616     var a = x;
617     var k = y;
618     while (true) {
619         if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
620         k = biShiftRight(k, 1);
621         if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
622         a = biMultiplyMod(a, a, m);
623     }
624     return result;
625 }
View Code

3.Barrett

 1 // BarrettMu, a class for performing Barrett modular reduction computations in
 2 // JavaScript.
 3 //
 4 // Requires BigInt.js.
 5 //
 6 // Copyright 2004-2005 David Shapiro.
 7 //
 8 // You may use, re-use, abuse, copy, and modify this code to your liking, but
 9 // please keep this header.
10 //
11 // Thanks!
12 // 
13 // Dave Shapiro
14 // dave@ohdave.com 
15 
16 function BarrettMu(m)
17 {
18     this.modulus = biCopy(m);
19     this.k = biHighIndex(this.modulus) + 1;
20     var b2k = new BigInt();
21     b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
22     this.mu = biDivide(b2k, this.modulus);
23     this.bkplus1 = new BigInt();
24     this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
25     this.modulo = BarrettMu_modulo;
26     this.multiplyMod = BarrettMu_multiplyMod;
27     this.powMod = BarrettMu_powMod;
28 }
29 
30 function BarrettMu_modulo(x)
31 {
32     var q1 = biDivideByRadixPower(x, this.k - 1);
33     var q2 = biMultiply(q1, this.mu);
34     var q3 = biDivideByRadixPower(q2, this.k + 1);
35     var r1 = biModuloByRadixPower(x, this.k + 1);
36     var r2term = biMultiply(q3, this.modulus);
37     var r2 = biModuloByRadixPower(r2term, this.k + 1);
38     var r = biSubtract(r1, r2);
39     if (r.isNeg) {
40         r = biAdd(r, this.bkplus1);
41     }
42     var rgtem = biCompare(r, this.modulus) >= 0;
43     while (rgtem) {
44         r = biSubtract(r, this.modulus);
45         rgtem = biCompare(r, this.modulus) >= 0;
46     }
47     return r;
48 }
49 
50 function BarrettMu_multiplyMod(x, y)
51 {
52     /*
53     x = this.modulo(x);
54     y = this.modulo(y);
55     */
56     var xy = biMultiply(x, y);
57     return this.modulo(xy);
58 }
59 
60 function BarrettMu_powMod(x, y)
61 {
62     var result = new BigInt();
63     result.digits[0] = 1;
64     var a = x;
65     var k = y;
66     while (true) {
67         if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
68         k = biShiftRight(k, 1);
69         if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
70         a = this.multiplyMod(a, a);
71     }
72     return result;
73 }
View Code

4.加密

 1 public static string BytesToHexString(byte[] input)
 2         {
 3             StringBuilder hexString = new StringBuilder(64);
 4 
 5             for (int i = 0; i < input.Length; i++)
 6             {
 7                 hexString.Append(String.Format("{0:X2}", input[i]));
 8             }
 9             return hexString.ToString();
10         }
View Code
1 private void init()
2         {
3             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
4             Session["private_key"] = rsa.ToXmlString(true);
5             RSAParameters parameter = rsa.ExportParameters(true);
6             ViewData["strPublicKeyExponent"] = LoginPasswordHelp.BytesToHexString(parameter.Exponent);
7             ViewData["strPublicKeyModulus"] = LoginPasswordHelp.BytesToHexString(parameter.Modulus);
8         }
View Code
1 setMaxDigits(129);//BigInt
2             var key = new RSAKeyPair('<%= Html.Encode(ViewData["strPublicKeyExponent"])%>', "", '<%= Html.Encode(ViewData["strPublicKeyModulus"])%>');//RSA
3             var pwdRtn = encryptedString(key, pwd);//RSA
View Code

 

 5.后台解密

 1 //转换为byte[]
 2  public static byte[] HexStringToBytes(string hex)
 3         {
 4             if (hex.Length == 0)
 5             {
 6                 return new byte[] { 0 };
 7             }
 8 
 9             if (hex.Length % 2 == 1)
10             {
11                 hex = "0" + hex;
12             }
13 
14             byte[] result = new byte[hex.Length / 2];
15 
16             for (int i = 0; i < hex.Length / 2; i++)
17             {
18                 result[i] = byte.Parse(hex.Substring(2 * i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
19             }
20 
21             return result;
22         }
23 
24 
25 string pwd = ""; 
26                 try
27                 {
28                     ////解密
29                     string strPwdToDecrypt = Request["pwd"];
30                     RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
31                     rsa.FromXmlString((string)Session["private_key"]);
32                     byte[] result = rsa.Decrypt(LoginPasswordHelp.HexStringToBytes(strPwdToDecrypt), false);
33                     System.Text.ASCIIEncoding enc = new ASCIIEncoding();
34                      pwd = enc.GetString(result);
35                 }
36                 catch (Exception ex)
37                 {
38                     HX.Common.Platform.Log(LogLevel.Error, ex);
39                     string errorMsg = lang == "en" ? "Login session is overdue, please reload it again!" : "登录会话已过期,请刷新后再试!";
40                     return Json(new { success = false, msg = errorMsg });
41                 }
View Code

 

posted @ 2017-03-08 15:21  AAABONE  阅读(1218)  评论(0编辑  收藏  举报