javascript实现rsa算法(支持微信小程序)

function strRsaCtxParams() { this.keyn; this.keye; this.keyd; this.keybits; }; function rsa_pkcs1_pad(orgdata, mode/*0:0填充,1:F填充, 2:不为0随机数填充*/, bits) { var outData = new Uint8Array(parseInt((bits + 7) / 8)); var i = 0; var j = 0; for (i = 0; i < outData.length; i++) { outData[i] = 0; } //return outData; //mode = 1; if (orgdata.length > outData.length - 4) { throw Error('数据长度过长导致不能填充'); } if (mode != 0 && mode != 1 && mode != 2) { throw Error('填充模式必须在0,1,2中选择'); } outData[0] = 0x00; outData[1] = mode; for (i = 2; i < outData.length - orgdata.length - 1; i++) { if (mode == 0) { outData[i] = 0; } else if (mode == 1) { outData[i] = 0xFF; } else if (mode == 2) { outData[i] = parseInt(Math.random() * 256) & 0xff; if (outData[i] == 0) { /* 简单点,为0改为1 */ outData[i] = 1; } } } //console.log("i1 = %d", i); outData[i] = 0; i++; j = 0; while (i < outData.length && j < orgdata.length) { outData[i] = orgdata[j]; i++; j++; } //console.log("i2 = %d", i); return outData; } function rsa_set_key(keyNArray, keyEArray, keyDArray) { var rsaCtxParams = new strRsaCtxParams(); //var i = 0; if (keyNArray == null || keyNArray.length <= 0) { throw Error('n的值不能为空'); } rsaCtxParams.keybits = CalArrayBits(keyNArray, keyNArray.length); rsaCtxParams.keyn = NN_Decode(keyNArray, keyNArray.length); //console.log("rsaCtxParams.keyn len = %d index0=%d index1=%d index63=%d", rsaCtxParams.keyn.length, rsaCtxParams.keyn[0], rsaCtxParams.keyn[1], rsaCtxParams.keyn[63]); if (keyEArray != null) { rsaCtxParams.keye = NN_Decode(keyEArray, keyEArray.length); } if (keyDArray != null) { rsaCtxParams.keyd = NN_Decode(keyDArray, keyDArray.length); } return rsaCtxParams; } function rsa_pub_cal(rsaCtxParams, lpIn) { var m = null; var c = null; var eDigits, nDigits; var outResult = null; var tmpInt = 0; if (rsaCtxParams.keyn == null || rsaCtxParams.keyn.length <= 0) { throw Error('n的值不能为空'); } if (rsaCtxParams.keye == null || rsaCtxParams.keye.length <= 0) { throw Error('e的值不能为空'); } m = NN_Decode(lpIn, lpIn.length); if (BignumCmp(m, rsaCtxParams.keyn) >= 0) { throw Error('输入数据不能大于等于n'); } //console.log("m len = %d", m.length); //printfInts("m", m, m.length); nDigits = NN_Digits(rsaCtxParams.keyn, 0, rsaCtxParams.keyn.length); eDigits = NN_Digits(rsaCtxParams.keye, 0, rsaCtxParams.keye.length); //console.log("nDigits = %d eDigits = %d", nDigits, eDigits); c = new Array(parseInt(((rsaCtxParams.keybits) + 31) / 32)); init_u32array(c, c.length); NN_ModExp(c, m, rsaCtxParams.keye, eDigits, rsaCtxParams.keyn, nDigits, rsaCtxParams); tmpInt = parseInt((rsaCtxParams.keybits + 7) / 8); outResult = new Uint8Array(tmpInt); NN_Encode(outResult, 0, tmpInt, c, 0, nDigits); return outResult; } function rsa_pri_cal(rsaCtxParams, lpIn) { var m = null; var c = null; var nDigits = 0; var dDigits = 0; var outResult = null; var tmpInt = 0; if (rsaCtxParams.keyn == null || rsaCtxParams.keyn.length <= 0) { throw Error('n的值不能为空'); } if (rsaCtxParams.keyd == null || rsaCtxParams.keyd.length <= 0) { throw Error('e的值不能为空'); } c = NN_Decode(lpIn, lpIn.length); if (BignumCmp(c, rsaCtxParams.keyn) >= 0) { throw Error('输入数据不能大于等于n'); } nDigits = NN_Digits(rsaCtxParams.keyn, 0, rsaCtxParams.keyn.length); dDigits = NN_Digits(rsaCtxParams.keyd, 0, rsaCtxParams.keyd.length); m = new Array(parseInt(((rsaCtxParams.keybits) + 31) / 32)); //console.log("pro0"); NN_ModExp(m, c, rsaCtxParams.keyd, dDigits, rsaCtxParams.keyn, nDigits, rsaCtxParams); //console.log("pro1"); tmpInt = parseInt((rsaCtxParams.keybits + 7) / 8); outResult = new Uint8Array(tmpInt); NN_Encode(outResult, 0, tmpInt, m, 0, nDigits); return outResult; } function NN_Encode(a, aindex, len, b, bindex, digits) { var t; var j; var i, u; for (i = 0, j = len - 1; i < digits && j >= 0; i++) { t = b[i + bindex]; for (u = 0; j >= 0 && u < 32; j--, u += 8) { a[j + aindex] = (t >>> u) & 0xffffffff; } } for (; j >= 0; j--) { a[j + aindex] = 0; } } function NN_ASSIGN_DIGIT(a, aindex, b, digits) { NN_AssignZero(a, aindex, digits); a[0] = b; } function DIGIT_2MSB(x) { //(unsigned int)(((x) >> (NN_DIGIT_BITS - 2)) & 3) return ((((x) >>> (32 - 2)) & 3) & 0xffffffff) >>> 0; } //var testI = 0; function NN_ModExp(a, b, c, cDigits, d, dDigits, rsaCtxParams) { var uPowerLen = parseInt((rsaCtxParams.keybits + 31) / 32); var bPower = new Array(3 * uPowerLen); var t = new Array(uPowerLen); var i = 0, j = 0, s = 0; var ci = 0; var ciBits = 0; init_u32array(bPower, bPower.length); //for (i = 0; i < bPower.length; i++) { // bPower[i] = 0; //} //console.log("dDigits = %d", dDigits); //printfInts("bPower", bPower, bPower.length); //printfInts("b", b, b.length); //throw Error("11"); //console.log("pro2"); NN_Assign(bPower, 0, b, 0, dDigits); //printfInts("bPower", bPower, bPower.length); //printfInts("b", b, b.length); //throw Error("223"); //console.log("pro3"); NN_ModMult(bPower, uPowerLen, bPower, 0, b, 0, d, 0, dDigits, rsaCtxParams); //console.log("pro4"); NN_ModMult(bPower, uPowerLen * 2, bPower, uPowerLen, b, 0, d, 0, dDigits, rsaCtxParams); //NN_Assign(bPower, uPowerLen, b, 0, dDigits); //NN_Assign(bPower, uPowerLen * 2, b, 0, dDigits); //printfIntsIndex("bPower0", bPower, 0, uPowerLen); //printfIntsIndex("bPower1", bPower, uPowerLen, uPowerLen); //printfIntsIndex("bPower2", bPower, uPowerLen * 2, uPowerLen); //console.log("pro5"); NN_ASSIGN_DIGIT(t, 0, 1, dDigits); //console.log("pro6"); cDigits = NN_Digits(c, 0, cDigits); //console.log("pro7"); for (i = cDigits - 1; i >= 0; i--) { //console.log("pro8"); ci = c[i]; ciBits = 32; if (i == (cDigits - 1)) { while (0 == DIGIT_2MSB(ci)) { //console.log("pro9"); ci <<= 2; ci &= 0xffffffff; //ciBits -= 2; ciBits = bn_u32_minus(ciBits, 2); } } for (j = 0; j < ciBits; j += 2, ci = (ci << 2) & 0xffffffff) { //console.log("pro10"); /* Compute t = t^4 * b^s mod d, where s = two MSB's of ci. */ NN_ModMult(t, 0, t, 0, t, 0, d, 0, dDigits, rsaCtxParams); //console.log("pro11"); NN_ModMult(t, 0, t, 0, t, 0, d, 0, dDigits, rsaCtxParams); //console.log("pro12"); s = DIGIT_2MSB(ci); //console.log("pro13"); if ((s) != 0) { //console.log("pro14"); //testI++; //console.log("testI = %d s = %d dDigits = %d", testI, s, dDigits); /*if (testI >= 412) { printfInts("t", t, 129); printfInts("d", d, 128); printfIntsIndex("bPower0", bPower, 0, 128); printfIntsIndex("bPower1", bPower, uPowerLen, 128); printfIntsIndex("bPower2", bPower, uPowerLen * 2, 128); exit(0); }*/ NN_ModMult(t, 0, t, 0, bPower, (s - 1) * uPowerLen, d, 0, dDigits, rsaCtxParams); //console.log("pro15"); } } } NN_Assign(a, 0, t, 0, dDigits); //printfInts("a", a, a.length); //printfInts("b", b, b.length); //printfInts("c", c, c.length); //printfInts("t", t, t.length); } function bn_u32_compare(uint1, uint2) { uint1 &= 0xffffffff; uint2 &= 0xffffffff; if ((uint1 & 0x80000000) == 0 && (uint2 & 0x80000000) == 0) { return uint1 > uint2 ? 1 : (uint1 == uint2 ? 0 : (-1)); } if ((uint1 & 0x80000000) != 0 && (uint2 & 0x80000000) != 0) { uint1 &= 0x7fffffff; uint2 &= 0x7fffffff; return uint1 > uint2 ? 1 : (uint1 == uint2 ? 0 : (-1)); } if ((uint1 & 0x80000000) != 0) { return 1; } else { return -1; } } function bn_u32_add(add1, add2) { var i = 0; var tmp = 0; var result = 0; for (i = 0; i < 4; i++) { tmp = ((add1 >>> (i * 8)) & 0xff) + ((add2 >>> (i * 8)) & 0xff) + tmp; result |= ((tmp & 0xff) << (i * 8)); tmp = tmp >>> 8; } return result & 0xffffffff; } function bn_u32_minus(minuend, subtractor) { var a = (minuend & 0xffffffff) >>> 0; var b = (subtractor & 0xffffffff) >>> 0; return (a - b) & 0xffffffff; } function NN_ModMult(a, aindex, b, bindex, c, cindex, d, dindex, digits, rsaCtxParams) { var t = new Array(2 * parseInt((rsaCtxParams.keybits + 31) / 32)); init_u32array(t, t.length); //console.log("pp0"); NN_Mult(t, 0, b, bindex, c, cindex, digits, rsaCtxParams); //printfIntsIndex("t", t, 0, 128); //printfIntsIndex("b", b, bindex, 128); //printfIntsIndex("c", c, cindex, 128); //console.log("pp1"); NN_Mod(a, aindex, t, 0, 2 * digits, d, dindex, digits, rsaCtxParams); } function NN_Mod(a, aindex, b, bindex, bDigits, c, cindex, cDigits, rsaCtxParams) { //NN_DIGIT t[2 * MAX_NN_DIGITS]; var t = new Array(2 * parseInt((rsaCtxParams.keybits + 31) / 32)); init_u32array(t, t.length); NN_Div(t, 0, a, aindex, b, bindex, bDigits, c, cindex, cDigits, rsaCtxParams); } function NN_DigitBits(a) { var i; for (i = 0
上一篇:Nature Electronics 用于语音识别的液体声传感器,基于悬浮在载液的钕-铁-硼磁性纳米颗粒


下一篇:JAVA学习日记(八)