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

简介: 1.RSA 1 // RSA, a suite of routines for performing RSA public-key computations in 2 // JavaScript.

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

 

目录
相关文章
|
3月前
|
Java 数据安全/隐私保护
对称加密、非对称加密与哈希摘要
本内容介绍了对称加密、非对称加密和哈希摘要的基本概念与区别。对称加密使用同一密钥加解密,速度快但需妥善保管密钥;非对称加密使用公钥加密、私钥解密,安全性高但速度较慢;哈希摘要通过提取数据特征用于完整性校验,能有效区分不同数据。
166 2
|
4月前
|
数据安全/隐私保护
解释对称加密、非对称加密、哈希摘要
加密技术分为对称加密与非对称加密。对称加密使用同一密钥进行加解密,速度快但需严保管密钥;非对称加密则用公钥加密、私钥解密,安全性高但速度较慢。哈希摘要用于验证数据完整性,代表原始数据特征。
162 0
|
4月前
|
存储 安全 数据处理
探讨对称加密与非对称加密的区别
综上所述,对称加密和非对称加密的选用取决于不同的安全需求、性能考量和应用情境。了解各自的特点和限制,才能有效地部署合理的加密策略,以确保数据通信的安全性和效率。
539 13
|
4月前
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
177 0
|
5月前
|
算法 数据安全/隐私保护
基于混沌加密的遥感图像加密算法matlab仿真
本项目实现了一种基于混沌加密的遥感图像加密算法MATLAB仿真(测试版本:MATLAB2022A)。通过Logistic映射与Baker映射生成混沌序列,对遥感图像进行加密和解密处理。程序分析了加解密后图像的直方图、像素相关性、信息熵及解密图像质量等指标。结果显示,加密图像具有良好的随机性和安全性,能有效保护遥感图像中的敏感信息。该算法适用于军事、环境监测等领域,具备加密速度快、密钥空间大、安全性高的特点。
|
9月前
|
弹性计算 算法 Linux
使用SM4算法加密LUKS格式磁盘
本文介绍了在Anolis 8操作系统使用cryptsetup对磁盘进行分区、加密和挂载的过程。采用SM4加密算法。具体步骤包括:初始化加密卷、解锁加密分区、格式化并挂载设备。最后,展示了如何取消挂载并关闭加密卷以确保数据安全。整个过程确保了磁盘数据的安全性和隐私保护。
667 2
使用SM4算法加密LUKS格式磁盘
|
12月前
|
安全 数据库 数据安全/隐私保护
对称加密与非对称加密的区别
对称加密与非对称加密的区别
1098 64
|
11月前
|
Java 数据安全/隐私保护
对称加密、非对称加密、哈希摘要
对称加密使用同一密钥进行加解密,速度快但需保密;非对称加密采用公钥加密、私钥解密,公钥可公开,安全性高但速度较慢,双向通信需双方各持一对密钥;哈希摘要是从数据中提取特征,用于数据完整性校验,不同数据的哈希值几乎不会相同。
162 0
|
安全 网络协议 网络安全
【HTTPS】对称加密和非对称加密
【HTTPS】对称加密和非对称加密
243 0
下一篇
oss云网关配置