前段时间在抓取某网页时发现,其登录密码是用js经过rsa加密后提交的。找到了它的rsa加密的js文件,我就在想能不能让c#直接调用js,于是就在百度了一下,还真找到了,于是整理了一下。
1、写了一个帮助类
1 using MSScriptControl; 2 using System; 3 using System.IO; 4 5 namespace Javascript 6 { 7 /// <summary> 8 /// JavascriptHelper 9 /// </summary> 10 public class JavascriptHelper 11 { 12 /// <summary> 13 /// ScriptControl 14 /// </summary> 15 private ScriptControl jsControl = null; 16 17 /// <summary> 18 /// 构造方法 19 /// </summary> 20 public JavascriptHelper() 21 { 22 this.jsControl = new ScriptControl(); 23 this.jsControl.UseSafeSubset = true; 24 this.jsControl.Language = "JScript"; 25 } 26 27 /// <summary> 28 /// 添加js文件 29 /// </summary> 30 /// <param name="filePath">js文件路径</param> 31 public void AddJavaScriptFile(string filePath) 32 { 33 if (!File.Exists(filePath)) 34 { 35 throw new Exception("文件" + filePath + "不存在。"); 36 } 37 38 string jsCode = File.ReadAllText(filePath); 39 this.jsControl.AddCode(jsCode); 40 } 41 42 /// <summary> 43 /// 添加js代码 44 /// </summary> 45 /// <param name="jsCode">js代码</param> 46 public void AddJavascriptCode(string jsCode) 47 { 48 this.jsControl.AddCode(jsCode); 49 } 50 51 /// <summary> 52 /// 执行js 53 /// </summary> 54 /// <param name="method">方法名</param> 55 /// <returns>结果</returns> 56 public dynamic Excecute(string method) 57 { 58 return this.jsControl.Eval(method); 59 } 60 } 61 }
2、引入找到的rsa的js文件,文件内容如下
1 /* 2 * RSA, a suite of routines for performing RSA public-key computations in JavaScript. 3 * Copyright 1998-2005 David Shapiro. 4 * Dave Shapiro 5 * dave@ohdave.com 6 * changed by Fuchun, 2010-05-06 7 * fcrpg2005@gmail.com 8 */ 9 var window = new Object(); 10 (function ($w) { 11 12 if (typeof $w.RSAUtils === 'undefined') var RSAUtils = $w.RSAUtils = {}; 13 14 var biRadixBase = 2; 15 var biRadixBits = 16; 16 var bitsPerDigit = biRadixBits; 17 var biRadix = 1 << 16; // = 2^16 = 65536 18 var biHalfRadix = biRadix >>> 1; 19 var biRadixSquared = biRadix * biRadix; 20 var maxDigitVal = biRadix - 1; 21 var maxInteger = 9999999999999998; 22 23 //maxDigits: 24 //Change this to accommodate your largest number size. Use setMaxDigits() 25 //to change it! 26 // 27 //In general, if you're working with numbers of size N bits, you'll need 2*N 28 //bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need 29 // 30 //1024 * 2 / 16 = 128 digits of storage. 31 // 32 var maxDigits; 33 var ZERO_ARRAY; 34 var bigZero, bigOne; 35 36 var BigInt = $w.BigInt = function (flag) { 37 if (typeof flag == "boolean" && flag == true) { 38 this.digits = null; 39 } else { 40 this.digits = ZERO_ARRAY.slice(0); 41 } 42 this.isNeg = false; 43 }; 44 45 RSAUtils.setMaxDigits = function (value) { 46 maxDigits = value; 47 ZERO_ARRAY = new Array(maxDigits); 48 for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0; 49 bigZero = new BigInt(); 50 bigOne = new BigInt(); 51 bigOne.digits[0] = 1; 52 }; 53 RSAUtils.setMaxDigits(20); 54 55 //The maximum number of digits in base 10 you can convert to an 56 //integer without JavaScript throwing up on you. 57 var dpl10 = 15; 58 59 RSAUtils.biFromNumber = function (i) { 60 var result = new BigInt(); 61 result.isNeg = i < 0; 62 i = Math.abs(i); 63 var j = 0; 64 while (i > 0) { 65 result.digits[j++] = i & maxDigitVal; 66 i = Math.floor(i / biRadix); 67 } 68 return result; 69 }; 70 71 //lr10 = 10 ^ dpl10 72 var lr10 = RSAUtils.biFromNumber(1000000000000000); 73 74 RSAUtils.biFromDecimal = function (s) { 75 var isNeg = s.charAt(0) == '-'; 76 var i = isNeg ? 1 : 0; 77 var result; 78 // Skip leading zeros. 79 while (i < s.length && s.charAt(i) == '0')++i; 80 if (i == s.length) { 81 result = new BigInt(); 82 } else { 83 var digitCount = s.length - i; 84 var fgl = digitCount % dpl10; 85 if (fgl == 0) fgl = dpl10; 86 result = RSAUtils.biFromNumber(Number(s.substr(i, fgl))); 87 i += fgl; 88 while (i < s.length) { 89 result = RSAUtils.biAdd(RSAUtils.biMultiply(result, lr10), RSAUtils.biFromNumber(Number(s.substr(i, dpl10)))); 90 i += dpl10; 91 } 92 result.isNeg = isNeg; 93 } 94 return result; 95 }; 96 97 RSAUtils.biCopy = function (bi) { 98 var result = new BigInt(true); 99 result.digits = bi.digits.slice(0); 100 result.isNeg = bi.isNeg; 101 return result; 102 }; 103 104 RSAUtils.reverseStr = function (s) { 105 var result = ""; 106 for (var i = s.length - 1; i > -1; --i) { 107 result += s.charAt(i); 108 } 109 return result; 110 }; 111 112 var hexatrigesimalToChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; 113 114 RSAUtils.biToString = function (x, radix) { // 2 <= radix <= 36 115 var b = new BigInt(); 116 b.digits[0] = radix; 117 var qr = RSAUtils.biDivideModulo(x, b); 118 var result = hexatrigesimalToChar[qr[1].digits[0]]; 119 while (RSAUtils.biCompare(qr[0], bigZero) == 1) { 120 qr = RSAUtils.biDivideModulo(qr[0], b); 121 digit = qr[1].digits[0]; 122 result += hexatrigesimalToChar[qr[1].digits[0]]; 123 } 124 return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result); 125 }; 126 127 RSAUtils.biToDecimal = function (x) { 128 var b = new BigInt(); 129 b.digits[0] = 10; 130 var qr = RSAUtils.biDivideModulo(x, b); 131 var result = String(qr[1].digits[0]); 132 while (RSAUtils.biCompare(qr[0], bigZero) == 1) { 133 qr = RSAUtils.biDivideModulo(qr[0], b); 134 result += String(qr[1].digits[0]); 135 } 136 return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result); 137 }; 138 139 var hexToChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; 140 141 RSAUtils.digitToHex = function (n) { 142 var mask = 0xf; 143 var result = ""; 144 for (i = 0; i < 4; ++i) { 145 result += hexToChar[n & mask]; 146 n >>>= 4; 147 } 148 return RSAUtils.reverseStr(result); 149 }; 150 151 RSAUtils.biToHex = function (x) { 152 var result = ""; 153 var n = RSAUtils.biHighIndex(x); 154 for (var i = RSAUtils.biHighIndex(x) ; i > -1; --i) { 155 result += RSAUtils.digitToHex(x.digits[i]); 156 } 157 return result; 158 }; 159 160 RSAUtils.charToHex = function (c) { 161 var ZERO = 48; 162 var NINE = ZERO + 9; 163 var littleA = 97; 164 var littleZ = littleA + 25; 165 var bigA = 65; 166 var bigZ = 65 + 25; 167 var result; 168 169 if (c >= ZERO && c <= NINE) { 170 result = c - ZERO; 171 } else if (c >= bigA && c <= bigZ) { 172 result = 10 + c - bigA; 173 } else if (c >= littleA && c <= littleZ) { 174 result = 10 + c - littleA; 175 } else { 176 result = 0; 177 } 178 return result; 179 }; 180 181 RSAUtils.hexToDigit = function (s) { 182 var result = 0; 183 var sl = Math.min(s.length, 4); 184 for (var i = 0; i < sl; ++i) { 185 result <<= 4; 186 result |= RSAUtils.charToHex(s.charCodeAt(i)); 187 } 188 return result; 189 }; 190 191 RSAUtils.biFromHex = function (s) { 192 var result = new BigInt(); 193 var sl = s.length; 194 for (var i = sl, j = 0; i > 0; i -= 4, ++j) { 195 result.digits[j] = RSAUtils.hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); 196 } 197 return result; 198 }; 199 200 RSAUtils.biFromString = function (s, radix) { 201 var isNeg = s.charAt(0) == '-'; 202 var istop = isNeg ? 1 : 0; 203 var result = new BigInt(); 204 var place = new BigInt(); 205 place.digits[0] = 1; // radix^0 206 for (var i = s.length - 1; i >= istop; i--) { 207 var c = s.charCodeAt(i); 208 var digit = RSAUtils.charToHex(c); 209 var biDigit = RSAUtils.biMultiplyDigit(place, digit); 210 result = RSAUtils.biAdd(result, biDigit); 211 place = RSAUtils.biMultiplyDigit(place, radix); 212 } 213 result.isNeg = isNeg; 214 return result; 215 }; 216 217 RSAUtils.biDump = function (b) { 218 return (b.isNeg ? "-" : "") + b.digits.join(" "); 219 }; 220 221 RSAUtils.biAdd = function (x, y) { 222 var result; 223 224 if (x.isNeg != y.isNeg) { 225 y.isNeg = !y.isNeg; 226 result = RSAUtils.biSubtract(x, y); 227 y.isNeg = !y.isNeg; 228 } else { 229 result = new BigInt(); 230 var c = 0; 231 var n; 232 for (var i = 0; i < x.digits.length; ++i) { 233 n = x.digits[i] + y.digits[i] + c; 234 result.digits[i] = n % biRadix; 235 c = Number(n >= biRadix); 236 } 237 result.isNeg = x.isNeg; 238 } 239 return result; 240 }; 241 242 RSAUtils.biSubtract = function (x, y) { 243 var result; 244 if (x.isNeg != y.isNeg) { 245 y.isNeg = !y.isNeg; 246 result = RSAUtils.biAdd(x, y); 247 y.isNeg = !y.isNeg; 248 } else { 249 result = new BigInt(); 250 var n, c; 251 c = 0; 252 for (var i = 0; i < x.digits.length; ++i) { 253 n = x.digits[i] - y.digits[i] + c; 254 result.digits[i] = n % biRadix; 255 // Stupid non-conforming modulus operation. 256 if (result.digits[i] < 0) result.digits[i] += biRadix; 257 c = 0 - Number(n < 0); 258 } 259 // Fix up the negative sign, if any. 260 if (c == -1) { 261 c = 0; 262 for (var i = 0; i < x.digits.length; ++i) { 263 n = 0 - result.digits[i] + c; 264 result.digits[i] = n % biRadix; 265 // Stupid non-conforming modulus operation. 266 if (result.digits[i] < 0) result.digits[i] += biRadix; 267 c = 0 - Number(n < 0); 268 } 269 // Result is opposite sign of arguments. 270 result.isNeg = !x.isNeg; 271 } else { 272 // Result is same sign. 273 result.isNeg = x.isNeg; 274 } 275 } 276 return result; 277 }; 278 279 RSAUtils.biHighIndex = function (x) { 280 var result = x.digits.length - 1; 281 while (result > 0 && x.digits[result] == 0)--result; 282 return result; 283 }; 284 285 RSAUtils.biNumBits = function (x) { 286 var n = RSAUtils.biHighIndex(x); 287 var d = x.digits[n]; 288 var m = (n + 1) * bitsPerDigit; 289 var result; 290 for (result = m; result > m - bitsPerDigit; --result) { 291 if ((d & 0x8000) != 0) break; 292 d <<= 1; 293 } 294 return result; 295 }; 296 297 RSAUtils.biMultiply = function (x, y) { 298 var result = new BigInt(); 299 var c; 300 var n = RSAUtils.biHighIndex(x); 301 var t = RSAUtils.biHighIndex(y); 302 var u, uv, k; 303 304 for (var i = 0; i <= t; ++i) { 305 c = 0; 306 k = i; 307 for (j = 0; j <= n; ++j, ++k) { 308 uv = result.digits[k] + x.digits[j] * y.digits[i] + c; 309 result.digits[k] = uv & maxDigitVal; 310 c = uv >>> biRadixBits; 311 //c = Math.floor(uv / biRadix); 312 } 313 result.digits[i + n + 1] = c; 314 } 315 // Someone give me a logical xor, please. 316 result.isNeg = x.isNeg != y.isNeg; 317 return result; 318 }; 319 320 RSAUtils.biMultiplyDigit = function (x, y) { 321 var n, c, uv; 322 323 result = new BigInt(); 324 n = RSAUtils.biHighIndex(x); 325 c = 0; 326 for (var j = 0; j <= n; ++j) { 327 uv = result.digits[j] + x.digits[j] * y + c; 328 result.digits[j] = uv & maxDigitVal; 329 c = uv >>> biRadixBits; 330 //c = Math.floor(uv / biRadix); 331 } 332 result.digits[1 + n] = c; 333 return result; 334 }; 335 336 RSAUtils.arrayCopy = function (src, srcStart, dest, destStart, n) { 337 var m = Math.min(srcStart + n, src.length); 338 for (var i = srcStart, j = destStart; i < m; ++i, ++j) { 339 dest[j] = src[i]; 340 } 341 }; 342 343 var highBitMasks = [0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF]; 344 345 RSAUtils.biShiftLeft = function (x, n) { 346 var digitCount = Math.floor(n / bitsPerDigit); 347 var result = new BigInt(); 348 RSAUtils.arrayCopy(x.digits, 0, result.digits, digitCount, result.digits.length - digitCount); 349 var bits = n % bitsPerDigit; 350 var rightBits = bitsPerDigit - bits; 351 for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { 352 result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) | ((result.digits[i1] & highBitMasks[bits]) >>> (rightBits)); 353 } 354 result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); 355 result.isNeg = x.isNeg; 356 return result; 357 }; 358 359 var lowBitMasks = [0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF]; 360 361 RSAUtils.biShiftRight = function (x, n) { 362 var digitCount = Math.floor(n / bitsPerDigit); 363 var result = new BigInt(); 364 RSAUtils.arrayCopy(x.digits, digitCount, result.digits, 0, x.digits.length - digitCount); 365 var bits = n % bitsPerDigit; 366 var leftBits = bitsPerDigit - bits; 367 for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { 368 result.digits[i] = (result.digits[i] >>> bits) | ((result.digits[i1] & lowBitMasks[bits]) << leftBits); 369 } 370 result.digits[result.digits.length - 1] >>>= bits; 371 result.isNeg = x.isNeg; 372 return result; 373 }; 374 375 RSAUtils.biMultiplyByRadixPower = function (x, n) { 376 var result = new BigInt(); 377 RSAUtils.arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); 378 return result; 379 }; 380 381 RSAUtils.biDivideByRadixPower = function (x, n) { 382 var result = new BigInt(); 383 RSAUtils.arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); 384 return result; 385 }; 386 387 RSAUtils.biModuloByRadixPower = function (x, n) { 388 var result = new BigInt(); 389 RSAUtils.arrayCopy(x.digits, 0, result.digits, 0, n); 390 return result; 391 }; 392 393 RSAUtils.biCompare = function (x, y) { 394 if (x.isNeg != y.isNeg) { 395 return 1 - 2 * Number(x.isNeg); 396 } 397 for (var i = x.digits.length - 1; i >= 0; --i) { 398 if (x.digits[i] != y.digits[i]) { 399 if (x.isNeg) { 400 return 1 - 2 * Number(x.digits[i] > y.digits[i]); 401 } else { 402 return 1 - 2 * Number(x.digits[i] < y.digits[i]); 403 } 404 } 405 } 406 return 0; 407 }; 408 409 RSAUtils.biDivideModulo = function (x, y) { 410 var nb = RSAUtils.biNumBits(x); 411 var tb = RSAUtils.biNumBits(y); 412 var origYIsNeg = y.isNeg; 413 var q, r; 414 if (nb < tb) { 415 // |x| < |y| 416 if (x.isNeg) { 417 q = RSAUtils.biCopy(bigOne); 418 q.isNeg = !y.isNeg; 419 x.isNeg = false; 420 y.isNeg = false; 421 r = biSubtract(y, x); 422 // Restore signs, 'cause they're references. 423 x.isNeg = true; 424 y.isNeg = origYIsNeg; 425 } else { 426 q = new BigInt(); 427 r = RSAUtils.biCopy(x); 428 } 429 return [q, r]; 430 } 431 432 q = new BigInt(); 433 r = x; 434 435 // Normalize Y. 436 var t = Math.ceil(tb / bitsPerDigit) - 1; 437 var lambda = 0; 438 while (y.digits[t] < biHalfRadix) { 439 y = RSAUtils.biShiftLeft(y, 1); 440 ++lambda; 441 ++tb; 442 t = Math.ceil(tb / bitsPerDigit) - 1; 443 } 444 // Shift r over to keep the quotient constant. We'll shift the 445 // remainder back at the end. 446 r = RSAUtils.biShiftLeft(r, lambda); 447 nb += lambda; // Update the bit count for x. 448 var n = Math.ceil(nb / bitsPerDigit) - 1; 449 450 var b = RSAUtils.biMultiplyByRadixPower(y, n - t); 451 while (RSAUtils.biCompare(r, b) != -1) { 452 ++q.digits[n - t]; 453 r = RSAUtils.biSubtract(r, b); 454 } 455 for (var i = n; i > t; --i) { 456 var ri = (i >= r.digits.length) ? 0 : r.digits[i]; 457 var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1]; 458 var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2]; 459 var yt = (t >= y.digits.length) ? 0 : y.digits[t]; 460 var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1]; 461 if (ri == yt) { 462 q.digits[i - t - 1] = maxDigitVal; 463 } else { 464 q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt); 465 } 466 467 var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1); 468 var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2); 469 while (c1 > c2) { 470 --q.digits[i - t - 1]; 471 c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1); 472 c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2); 473 } 474 475 b = RSAUtils.biMultiplyByRadixPower(y, i - t - 1); 476 r = RSAUtils.biSubtract(r, RSAUtils.biMultiplyDigit(b, q.digits[i - t - 1])); 477 if (r.isNeg) { 478 r = RSAUtils.biAdd(r, b); 479 --q.digits[i - t - 1]; 480 } 481 } 482 r = RSAUtils.biShiftRight(r, lambda); 483 // Fiddle with the signs and stuff to make sure that 0 <= r < y. 484 q.isNeg = x.isNeg != origYIsNeg; 485 if (x.isNeg) { 486 if (origYIsNeg) { 487 q = RSAUtils.biAdd(q, bigOne); 488 } else { 489 q = RSAUtils.biSubtract(q, bigOne); 490 } 491 y = RSAUtils.biShiftRight(y, lambda); 492 r = RSAUtils.biSubtract(y, r); 493 } 494 // Check for the unbelievably stupid degenerate case of r == -0. 495 if (r.digits[0] == 0 && RSAUtils.biHighIndex(r) == 0) r.isNeg = false; 496 497 return [q, r]; 498 }; 499 500 RSAUtils.biDivide = function (x, y) { 501 return RSAUtils.biDivideModulo(x, y)[0]; 502 }; 503 504 RSAUtils.biModulo = function (x, y) { 505 return RSAUtils.biDivideModulo(x, y)[1]; 506 }; 507 508 RSAUtils.biMultiplyMod = function (x, y, m) { 509 return RSAUtils.biModulo(RSAUtils.biMultiply(x, y), m); 510 }; 511 512 RSAUtils.biPow = function (x, y) { 513 var result = bigOne; 514 var a = x; 515 while (true) { 516 if ((y & 1) != 0) result = RSAUtils.biMultiply(result, a); 517 y >>= 1; 518 if (y == 0) break; 519 a = RSAUtils.biMultiply(a, a); 520 } 521 return result; 522 }; 523 524 RSAUtils.biPowMod = function (x, y, m) { 525 var result = bigOne; 526 var a = x; 527 var k = y; 528 while (true) { 529 if ((k.digits[0] & 1) != 0) result = RSAUtils.biMultiplyMod(result, a, m); 530 k = RSAUtils.biShiftRight(k, 1); 531 if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break; 532 a = RSAUtils.biMultiplyMod(a, a, m); 533 } 534 return result; 535 }; 536 537 $w.BarrettMu = function (m) { 538 this.modulus = RSAUtils.biCopy(m); 539 this.k = RSAUtils.biHighIndex(this.modulus) + 1; 540 var b2k = new BigInt(); 541 b2k.digits[2 * this.k] = 1; // b2k = b^(2k) 542 this.mu = RSAUtils.biDivide(b2k, this.modulus); 543 this.bkplus1 = new BigInt(); 544 this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1) 545 this.modulo = BarrettMu_modulo; 546 this.multiplyMod = BarrettMu_multiplyMod; 547 this.powMod = BarrettMu_powMod; 548 }; 549 550 function BarrettMu_modulo(x) { 551 var $dmath = RSAUtils; 552 var q1 = $dmath.biDivideByRadixPower(x, this.k - 1); 553 var q2 = $dmath.biMultiply(q1, this.mu); 554 var q3 = $dmath.biDivideByRadixPower(q2, this.k + 1); 555 var r1 = $dmath.biModuloByRadixPower(x, this.k + 1); 556 var r2term = $dmath.biMultiply(q3, this.modulus); 557 var r2 = $dmath.biModuloByRadixPower(r2term, this.k + 1); 558 var r = $dmath.biSubtract(r1, r2); 559 if (r.isNeg) { 560 r = $dmath.biAdd(r, this.bkplus1); 561 } 562 var rgtem = $dmath.biCompare(r, this.modulus) >= 0; 563 while (rgtem) { 564 r = $dmath.biSubtract(r, this.modulus); 565 rgtem = $dmath.biCompare(r, this.modulus) >= 0; 566 } 567 return r; 568 } 569 570 function BarrettMu_multiplyMod(x, y) { 571 /* 572 x = this.modulo(x); 573 y = this.modulo(y); 574 */ 575 var xy = RSAUtils.biMultiply(x, y); 576 return this.modulo(xy); 577 } 578 579 function BarrettMu_powMod(x, y) { 580 var result = new BigInt(); 581 result.digits[0] = 1; 582 var a = x; 583 var k = y; 584 while (true) { 585 if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); 586 k = RSAUtils.biShiftRight(k, 1); 587 if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break; 588 a = this.multiplyMod(a, a); 589 } 590 return result; 591 } 592 593 var RSAKeyPair = function (encryptionExponent, decryptionExponent, modulus) { 594 var $dmath = RSAUtils; 595 this.e = $dmath.biFromHex(encryptionExponent); 596 this.d = $dmath.biFromHex(decryptionExponent); 597 this.m = $dmath.biFromHex(modulus); 598 // We can do two bytes per digit, so 599 // chunkSize = 2 * (number of digits in modulus - 1). 600 // Since biHighIndex returns the high index, not the number of digits, 1 has 601 // already been subtracted. 602 this.chunkSize = 2 * $dmath.biHighIndex(this.m); 603 this.radix = 16; 604 this.barrett = new $w.BarrettMu(this.m); 605 }; 606 607 RSAUtils.getKeyPair = function (encryptionExponent, decryptionExponent, modulus) { 608 return new RSAKeyPair(encryptionExponent, decryptionExponent, modulus); 609 }; 610 611 if (typeof $w.twoDigit === 'undefined') { 612 $w.twoDigit = function (n) { 613 return (n < 10 ? "0" : "") + String(n); 614 }; 615 } 616 617 // Altered by Rob Saunders (rob@robsaunders.net). New routine pads the 618 // string after it has been converted to an array. This fixes an 619 // incompatibility with Flash MX's ActionScript. 620 RSAUtils.encryptedString = function (key, s) { 621 var a = []; 622 var sl = s.length; 623 var i = 0; 624 while (i < sl) { 625 a[i] = s.charCodeAt(i); 626 i++; 627 } 628 629 while (a.length % key.chunkSize != 0) { 630 a[i++] = 0; 631 } 632 633 var al = a.length; 634 var result = ""; 635 var j, k, block; 636 for (i = 0; i < al; i += key.chunkSize) { 637 block = new BigInt(); 638 j = 0; 639 for (k = i; k < i + key.chunkSize; ++j) { 640 block.digits[j] = a[k++]; 641 block.digits[j] += a[k++] << 8; 642 } 643 var crypt = key.barrett.powMod(block, key.e); 644 var text = key.radix == 16 ? RSAUtils.biToHex(crypt) : RSAUtils.biToString(crypt, key.radix); 645 result += text + " "; 646 } 647 return result.substring(0, result.length - 1); // Remove last space. 648 }; 649 650 RSAUtils.decryptedString = function (key, s) { 651 var blocks = s.split(" "); 652 var result = ""; 653 var i, j, block; 654 for (i = 0; i < blocks.length; ++i) { 655 var bi; 656 if (key.radix == 16) { 657 bi = RSAUtils.biFromHex(blocks[i]); 658 } else { 659 bi = RSAUtils.biFromString(blocks[i], key.radix); 660 } 661 block = key.barrett.powMod(bi, key.d); 662 for (j = 0; j <= RSAUtils.biHighIndex(block) ; ++j) { 663 result += String.fromCharCode(block.digits[j] & 255, block.digits[j] >> 8); 664 } 665 } 666 // Remove trailing null, if any. 667 if (result.charCodeAt(result.length - 1) == 0) { 668 result = result.substring(0, result.length - 1); 669 } 670 return result; 671 }; 672 RSAUtils.setMaxDigits(130); 673 })(window);
注意最后一行的window对象参数。如果这段js在浏览器中执行,是没有问题的,因为浏览器中有window这个对象。但是以现在这种方式来加载js是不存在window对象的,运行的时候就会报错。解决办法就是自己定义一个window对象,所以在第一有了"var window = new Object();"。
3、rsa是非对称加密算法,所以客户端要有其公钥,找到存放公钥的js文件,引入之。
1 function encrypt(name){ 2 var key = window.RSAUtils.getKeyPair("010001", "", "0098471b9a05c816ee949b4fe93520a8681a14e65d7a0501221136951a52a3b76cf9e2375e45aca1ad6fc9f00b401ece966a1f8fb521dd9de4215c90b7e9cd77b1c7d2f6e9b7aba6f94322d7375cbb321be653826d921030b6ef9fd453a7ece0ae4785a6166dd5d1560f3992cbad493201bb18616251610890bd0ea6736c346e15"); 3 var result = window.RSAUtils.encryptedString(key, name); 4 return result; 5 }
4、测试
1 using System; 2 using System.IO; 3 4 namespace Javascript 5 { 6 public class Program 7 { 8 public static void Main(string[] args) 9 { 10 string plantext = "123456"; 11 string ciphertext = Rsa(plantext); 12 Console.WriteLine(ciphertext); 13 Console.ReadLine(); 14 } 15 16 /// <summary> 17 /// rsa加密算法 18 /// </summary> 19 /// <param name="plantext">明文</param> 20 /// <returns>密文</returns> 21 private static string Rsa(string plantext) 22 { 23 JavascriptHelper jsHelper = new JavascriptHelper(); 24 AddJSFile(jsHelper); 25 string method = string.Format("encrypt('{0}');", plantext); 26 string ciphertext = jsHelper.Excecute(method).ToString(); 27 return ciphertext; 28 } 29 30 /// <summary> 31 /// 添加js文件 32 /// </summary> 33 /// <param name="jsHelper">JavascriptHelper</param> 34 private static void AddJSFile(JavascriptHelper jsHelper) 35 { 36 string path = string.Empty; 37 path = AppDomain.CurrentDomain.BaseDirectory + @"js\security.js"; 38 jsHelper.AddJavaScriptFile(path); 39 40 path = AppDomain.CurrentDomain.BaseDirectory + @"js\rsa.js"; 41 jsHelper.AddJavaScriptFile(path); 42 } 43 } 44 }