概述:
本代码是本人从c代码上转换成的javascript代码,本人踏踏实实改了一个星期(累死我了),反反复复测试验证通过的。公钥计算快,私钥计算很慢。
在微信小程序上测试验证通过的,和我们常用的文件wxapp_rsa.js对比
1、代码少,才30k左右,而wxapp_rsa.js有400k;
2、功能少了对公钥文件解析(很麻烦,我基本上不会在前端用到),取代直接传密钥的各个部分(公钥指数模,私钥指数模);
3、功能少了base64处理,这功能简单很容易其他地方找到;
测试平台:
已经在如下环境中测试通过,其他平台(浏览器)应该也不会有问题:
1、nodejs中node.exe运行
2、微信小程序
功能代码:
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; i < 32; i++, a = ((a >>> 1) & 0xffffffff)) {if (a == 0) {break;}}return (i);
}function NN_LShift(a, aindex, b, bindex, c, digits) {var temp, carry = 0;var tmpbindex = 0;var tmpaindex = 0;var t;if (c < 32 && digits != 0) {t = 32 - c;do {temp = b[tmpbindex + bindex];//b++;tmpbindex++;//*a = (temp << c) | carry;a[tmpaindex + aindex] = ((temp << c) | carry) & 0xffffffff;//a++;tmpaindex++;carry = (c != 0 ? (temp >>> t) : 0) & 0xffffffff;digits--;if (digits == 0) {break;}} while (true);}return (carry) & 0xffffffff;
}function NN_RShift(a, aindex, b, bindex, c, digits) {var temp = 0,carry = 0;var tmpbindex = 0;var tmpaindex = 0;var t = 0;if (c < 32 && digits != 0) {//if(digits) {t = 32 - c;do {digits--;//temp = *(b+digits);temp = b[digits + bindex];//*(a+digits) = ((temp >> c) | carry);a[digits + aindex] = ((temp >>> c) | carry) & 0xffffffff;carry = (c != 0 ? (temp << t) : 0) & 0xffffffff;} while (digits != 0);}return ((carry) & 0xffffffff) >>> 0;
}function TO_HIGH_HALF(x) {return ((x << 16) & 0xffffffff) >>> 0;
}function subdigitmult(a, aindex, b, bindex, c, d, dindex, digits) {var borrow = 0,thigh = 0,tlow = 0;var i = 0;var arr = new Array(2);borrow = 0;if (c != 0) {for (i = 0; i < digits; i++) {//function dmult(a, b, high, highindex, low, lowindex)//dmult(c, d[i], &thigh, &tlow);arr[0] = thigh;arr[1] = tlow;dmult(c, d[i + dindex], arr, 0, arr, 1);thigh = arr[0];tlow = arr[1];//a[i] = b[i] - borrow;a[i + aindex] = bn_u32_minus(b[i + bindex], borrow);//if((a[i]) > (MAX_NN_DIGIT - borrow)) {if (bn_u32_compare(a[i + aindex], bn_u32_minus(0xffffffff, borrow)) > 0) {borrow = 1;} else {borrow = 0;}//a[i] -= tlow;a[i + aindex] = bn_u32_minus(a[i + aindex], tlow);//if((a[i]) > (MAX_NN_DIGIT - tlow)) {if (bn_u32_compare(a[i + aindex], bn_u32_minus(0xffffffff, tlow)) > 0) {//borrow++;borrow = bn_u32_add(borrow, 1);}//borrow += thigh;borrow = bn_u32_add(borrow, thigh);}}return (borrow) & 0xffffffff;
}function NN_Cmp(a, aindex, b, bindex, digits) {if (digits != 0) {do {digits--;if ((a[digits + aindex] >>> 16) > (b[digits + bindex] >>> 16)) {return 1;}if ((a[digits + aindex] >>> 16) < (b[digits + bindex] >>> 16)) {return -1;}if ((a[digits + aindex] & 0xffff) > (b[digits + bindex] & 0xffff)) {return 1;}if ((a[digits + aindex] & 0xffff) < (b[digits + bindex] & 0xffff)) {return -1;}//if(*(a+digits) > *(b+digits))// return(1);//if(*(a+digits) < *(b+digits))// return(-1);} while (digits != 0);}return (0);
}function NN_Sub(a, aindex, b, bindex, c, cindex, digits) {var temp = 0,borrow = 0;var tmpaindex = 0,tmpbindex = 0,tmpcindex = 0;if (digits != 0)do {//temp = (*b) - borrow;temp = bn_u32_minus(b[tmpbindex + bindex], borrow);//b++;//b = bn_u32_add(b, 1);tmpbindex++;//if(temp == MAX_NN_DIGIT) {if (bn_u32_compare(temp, 0xffffffff) == 0) {//temp = MAX_NN_DIGIT - (*c);temp = bn_u32_minus(0xffffffff, c[tmpcindex + cindex]);//c++;tmpcindex++;} else {//temp -= (*c);temp = bn_u32_minus(temp, c[tmpcindex + cindex]);//if((temp) > (MAX_NN_DIGIT - (*c))) {if (bn_u32_compare(temp, bn_u32_minus(0xffffffff, c[tmpcindex + cindex])) > 0) {borrow = 1;} else {borrow = 0;}//c++;tmpcindex++;}//*a = temp;a[tmpaindex + aindex] = temp & 0xffffffff;//a++;tmpaindex++;digits--;if (digits == 0) {break;}} while (true);return (borrow);
}//var test2 = 0;
//var testI = 0;
function NN_Div(a, aindex, b, bindex, c, cindex, cDigits, d, dindex, dDigits, rsaCtxParams) {//NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], s;//NN_DIGIT t[2], u, v, *ccptr;//NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;//int i;//unsigned int ddDigits, shift;var cc = new Array(2 * parseInt((rsaCtxParams.keybits + 31) / 32) + 1);var dd = new Array(2 * parseInt((rsaCtxParams.keybits + 31) / 32));var t = new Array(2);var ddDigits = 0;var shift = 0;var s, u, v;var ai;var cHigh, cLow, aHigh, aLow;var i = 0;//var ccptrindex = 0;init_u32array(cc, cc.length);init_u32array(dd, dd.length);NN_AssignZero(dd, 0, dd.length);ddDigits = NN_Digits(d, dindex, dDigits);if (ddDigits == 0) {return;}shift = 32 - NN_DigitBits(d[dindex + ddDigits - 1]);//console.log("shift = %d", shift);NN_AssignZero(cc, 0, ddDigits);cc[cDigits] = NN_LShift(cc, 0, c, 0, shift, cDigits);//console.log("cc[cDigits] = %d", cc[cDigits]);NN_LShift(dd, 0, d, 0, shift, ddDigits);s = dd[ddDigits - 1];//console.log("s = %d", s);//printfInts("cc", cc, cc.length);//printfInts("dd", dd, dd.length);//throw Error("111");NN_AssignZero(a, aindex, cDigits);//throw Error("11222");//test2 = 0;for (i = cDigits - ddDigits; i >= 0; i--) {test2++;//if (testI >= 412) {// console.log("test2 = %d", test2);//}if (bn_u32_compare(s, 0xffffffff) == 0) {ai = (cc[i + ddDigits]) & 0xffffffff;} else {s = bn_u32_add(s, 1);cHigh = HIGH_HALF(s);cLow = LOW_HALF(s);t[0] = cc[i + ddDigits - 1];t[1] = cc[i + ddDigits];//if (testI >= 412 && test2 >= 13) console.log("t10 = %d %d", t[0], t[1]);if (cHigh == 0xffff) {aHigh = HIGH_HALF(t[1]);//if (testI >= 412 && test2 >= 13) console.log("aHigh1=%d", aHigh);} else {aHigh = parseInt((t[1] >>> 0) / ((cHigh >>> 0) + 1));//if (testI >= 412 && test2 >= 13) console.log("aHigh2=%d", aHigh);}u = ((aHigh >>> 0) * (cLow >>> 0)) & 0xffffffff;v = ((aHigh >>> 0) * (cHigh >>> 0)) & 0xffffffff;//if (testI >= 412 && test2 >= 13) console.log("u = %d v = %d aHigh = %d cLow = %d cHigh = %d", u, v, aHigh, cLow, cHigh);//if (testI >= 412 && test2 >= 13) console.log("t9 = %d %d", t[0], t[1]);t[0] = bn_u32_minus(t[0], TO_HIGH_HALF(u));//if (testI >= 412 && test2 >= 13) console.log("t91 = %d %d u = %d", t[0], t[1], u);if (bn_u32_compare(t[0], bn_u32_minus(0xffffffff, TO_HIGH_HALF(u))) > 0) {t[1] = bn_u32_minus(t[1], 1);}//if (testI >= 412 && test2 >= 13) console.log("t8 = %d %d", t[0], t[1]);//if (testI >= 412 && test2 >= 13) console.log("t[0] = %d t[1] = %d", t[0], t[1]);t[1] = bn_u32_minus(t[1], HIGH_HALF(u));//if (testI >= 412 && test2 >= 13) console.log("t[0] = %d t[1] = %d", t[0], t[1]);t[1] = bn_u32_minus(t[1], v);//if (testI >= 412 && test2 >= 13) console.log("t[0] = %d t[1] = %d", t[0], t[1]);//eeeek;//if (testI >= 412 && test2 >= 13) console.log("t7 = %d %d cHigh = %d, cLow = %d bn_u32_compare(t[0], cLow) = %d", t[0], t[1], cHigh, cLow, bn_u32_compare(t[0], cLow));while (bn_u32_compare(t[1], cHigh) > 0 || (bn_u32_compare(t[1], cHigh) == 0 && bn_u32_compare(t[0], TO_HIGH_HALF(cLow)) >= 0)) {//if (testI >= 412 && test2 >= 13) {// console.log("rd t[0] = %d t[1] = %d cLow = %d cHigh = %d", t[0], t[1], cLow, cHigh);// throw Error("");//}t[0] = bn_u32_minus(t[0], TO_HIGH_HALF(cLow));if (bn_u32_compare(t[0], bn_u32_minus(0xffffffff, TO_HIGH_HALF(cLow))) > 0) {t[1] = bn_u32_minus(t[1], 1);}t[1] = bn_u32_minus(t[1], cHigh);aHigh = bn_u32_add(aHigh, 1);}//if (testI >= 412 && test2 >= 13)console.log("t6 = %d %d cHigh = %d, cLow = %d", t[0], t[1], cHigh, cLow);if (bn_u32_compare(cHigh, 0xffff) == 0) {aLow = LOW_HALF(t[1]) & 0xffffffff;//console.log("aLow1 = %d ", aLow);} else {//aLow = parseInt((((TO_HIGH_HALF (t[1]) + HIGH_HALF (t[0])) >>> 0) & 0xffffffff) / bn_u32_add(cHigh, 1));aLow = (TO_HIGH_HALF(t[1]) >>> 0) + ((HIGH_HALF(t[0]) & 0xffffffff) >>> 0);aLow = parseInt(aLow / bn_u32_add(cHigh, 1)) & 0xffffffff;aLow &= 0xffffffff;//console.log("aLow2 = %d ", aLow);}u = ((aLow >>> 0) * (cLow >>> 0)) & 0xffffffff;v = ((aLow >>> 0) * (cHigh >>> 0)) & 0xffffffff;//(*t) -= u;//console.log("t5 = %d %d u = %d aLow = %d cLow = %d cHigh = %d", t[0], t[1], u, aLow, cLow, cHigh);t[0] = bn_u32_minus(t[0], u);//console.log("t4 = %d %d", t[0], t[1]);//if ((*t) > (MAX_NN_DIGIT - u)) {if (bn_u32_compare(t[0], bn_u32_minus(0xffffffff, u)) > 0) {//t[1]--;t[1] = bn_u32_minus(t[1], 1);}//console.log("t3 = %d %d", t[0], t[1]);//(*t) -= TO_HIGH_HALF (v);t[0] = bn_u32_minus(t[0], TO_HIGH_HALF(v));//console.log("t2 = %d %d", t[0], t[1]);//if ((*t) > (MAX_NN_DIGIT - TO_HIGH_HALF (v))) {if (bn_u32_compare(t[0], bn_u32_minus(0xffffffff, TO_HIGH_HALF(v))) > 0) {//t[1]--;t[1] = bn_u32_minus(t[1], 1);}//console.log("t1 = %d %d", t[0], t[1]);//*(t+1) -= HIGH_HALF (v);t[1] = bn_u32_minus(t[1], HIGH_HALF(v));//console.log("t0 = %d %d", t[0], t[1]);//console.log("ai1=%d aHigh = %d aLow = %d t[0] = %d t[1] = %d", ai, aHigh, aLow, t[0], t[1]);//while ((*(t+1) > 0) || ((*(t+1) == 0) && (*t) >= s)) {while (bn_u32_compare(t[1], 0) > 0 || (t[1] == 0 && bn_u32_compare(t[0], s) >= 0)) {//(*t) -= s;t[0] = bn_u32_minus(t[0], s);//if ((*t) > (MAX_NN_DIGIT - s)) {if (bn_u32_compare(t[0], bn_u32_minus(0xffffffff, s)) > 0) {t[1]--;}//aLow++;aLow = bn_u32_add(aLow, 1);}//ai = TO_HIGH_HALF (aHigh) + aLow;ai = bn_u32_add(TO_HIGH_HALF(aHigh), aLow);//console.log("ai0=%d aHigh = %d aLow = %d", ai, aHigh, aLow);//s--;s = bn_u32_minus(s, 1);//console.log("cHigh = %d cLow = %d", cHigh, cLow);//console.log("s = %d ai = %d t[0] = %d t[1] = %d cHigh = %d cLow = %d aHigh = %d aLow = %d u = %d v = %d", // s, ai, t[0], t[1], cHigh, cLow, aHigh, aLow, u, v);//cc[i+ddDigits] -= subdigitmult(&cc[i], &cc[i], ai, dd, ddDigits);//printfIntsIndex("cc", cc, 0, cc.length);//printfIntsIndex("dd", dd, 0, dd.length);//console.log("ai = %d ddDigits = %d i = %d", ai, ddDigits, i);cc[i + ddDigits] = bn_u32_minus(cc[i + ddDigits], subdigitmult(cc, i, cc, i, ai, dd, 0, ddDigits));//console.log("cc[i+ddDigits] = %d", cc[i+ddDigits]);//printfIntsIndex("cc", cc, 0, cc.length);//printfIntsIndex("dd", dd, 0, dd.length);//console.log("ddDigits = %d", ddDigits);//testI++//console.log("testI = %d", testI);//console.log("NN_Cmp(cc, i, dd, 0, ddDigits) = %d", NN_Cmp(cc, i, dd, 0, ddDigits));//if (testI > 2) {//throw Error("988");//}//console.log("testI = %d", testI);while (cc[i + ddDigits] != 0 || NN_Cmp(cc, i, dd, 0, ddDigits) >= 0) {// console.log("0 cc[i+ddDigits] = %d ai\n", cc[i+ddDigits]);ai = bn_u32_add(ai, 1);cc[i + ddDigits] = bn_u32_minus(cc[i + ddDigits], NN_Sub(cc, i, cc, i, dd, 0, ddDigits));//console.log("1 cc[i+ddDigits] = %d ai\n", cc[i+ddDigits]);//console.log("ai");//throw Error("9612332");}a[i + aindex] = ai & 0xffffffff;//throw Error("9632");}}//throw Error("987412");NN_AssignZero(b, bindex, dDigits);NN_RShift(b, bindex, cc, 0, shift, ddDigits);//console.log("shift = %d ddDigits = %d", shift, ddDigits);//printfIntsIndex("b", b, bindex, ddDigits);//throw Error("888");
}//var testi = 0;
function NN_Mult(a, aindex, b, bindex, c, cindex, digits, rsaCtxParams) {var t = new Array(2 * parseInt((rsaCtxParams.keybits + 31) / 32));var dhigh = 0xffffffff >>> 0,dlow = 0xffffffff >>> 0,carry = 0xffffffff >>> 0;var bDigits, cDigits, i, j;var tmpAr = new Array(2);init_u32array(t, t.length);init_u32array(tmpAr, tmpAr.length);//printfIntsIndex("a", a, aindex, parseInt((rsaCtxParams.keybits + 31) / 32));//printfIntsIndex("b", b, bindex, parseInt((rsaCtxParams.keybits + 31) / 32));//printfIntsIndex("c", c, cindex, parseInt((rsaCtxParams.keybits + 31) / 32));//throw Error("9988");tmpAr[0] = 0xffffffff >>> 0;tmpAr[1] = 0xffffffff >>> 0;for (i = 0; i < t.length; i++) {t[i] = 0xffffffff >>> 0;}NN_AssignZero(t, 0, t.length);bDigits = NN_Digits(b, bindex, digits);cDigits = NN_Digits(c, cindex, digits);for (i = 0; i < bDigits; i++) {carry = 0;if (b[i + bindex] != 0) {for (j = 0; j < cDigits; j++) {tmpAr[0] = dhigh;tmpAr[1] = dlow;//console.log("%d %d", b[i + bindex], c[j + cindex]);dmult(b[i + bindex], c[j + cindex], tmpAr, 0, tmpAr, 1);dhigh = tmpAr[0];dlow = tmpAr[1];//*(t+(i+j)) = *(t+(i+j)) + carry;//console.log("0t%d=%d dlow = %d dhigh = %d carry = %d", i + j, t[i + j], dlow, dhigh, carry);//testi++;//if (testi > 1) {// throw Error("ll");//}t[i + j] += carry;t[i + j] &= 0xffffffff;//console.log("1t%d=%d dlow = %d dhigh = %d carry = %d", i + j, t[i + j], dlow, dhigh, carry);//if((*(t+(i+j))) < carry) {//if (t[i + j] < carry) {if (bn_u32_compare(t[i + j], carry) < 0) {carry = 1;} else {carry = 0;}//*(t+(i+j)) += dlow;t[i + j] += dlow;t[i + j] &= 0xffffffff;//console.log("2t%d=%d dlow = %d dhigh = %d carry = %d", i + j, t[i + j], dlow, dhigh, carry);//if((*(t+(i+j))) < dlow) {//if (t[i + j] < dlow) {if (bn_u32_compare(t[i + j], dlow) < 0) {//console.log("carry add");carry++;}carry += dhigh;carry &= 0xffffffff}//throw Error("aaa");}//*(t+(i+cDigits)) += carry;t[i + cDigits] += carry;t[i + cDigits] &= 0xffffffff;}//printfIntsIndex("t", t, 0, t.length);//throw Error("9986");NN_Assign(a, 0, t, 0, 2 * digits);//printfIntsIndex("a", a, aindex, parseInt((rsaCtxParams.keybits + 31) / 32));//printfIntsIndex("b", b, bindex, parseInt((rsaCtxParams.keybits + 31) / 32));//printfIntsIndex("c", c, cindex, parseInt((rsaCtxParams.keybits + 31) / 32));//throw Error("3356");
}function LOW_HALF(val) {return val & 0xffff;
}function HIGH_HALF(val) {return (val >>> 16) & 0xffff;
}function init_u32array(array, len) {var i = 0;for (i = 0; i < len; i++) {array[i] = 0xffffffff >>> 0;}
}function dmult(a, b, high, highindex, low, lowindex) {var al = 0xffffffff >>> 0;var ah = 0xffffffff >>> 0;var bl = 0xffffffff >>> 0;var bh = 0xffffffff >>> 0;var m1 = 0xffffffff >>> 0;var m2 = 0xffffffff >>> 0;var m = 0xffffffff >>> 0;var ml = 0xffffffff >>> 0;var mh = 0xffffffff >>> 0;var carry = 0xffffffff >>> 0;carry = 0;al = LOW_HALF(a);ah = HIGH_HALF(a);bl = LOW_HALF(b);bh = HIGH_HALF(b);low[lowindex] = (al * bl) & 0xffffffff;high[highindex] = (ah * bh) & 0xffffffff;//console.log("low[lowindex] = %d high[highindex] = %d", low[lowindex], high[highindex]);m1 = (al * bh) & 0xffffffff;m2 = (ah * bl) & 0xffffffff;m = (m1 + m2) & 0xffffffff;if (bn_u32_compare(m, m1) < 0) {carry = (1 << 16) & 0xffffffff; //(NN_DIGIT_BITS / 2);}ml = (m & 0xffff) << 16; //(NN_DIGIT_BITS / 2);mh = (m >> 16) & 0xffff; //(NN_DIGIT_BITS / 2);low[lowindex] += ml;if (bn_u32_compare(low[lowindex], ml) < 0) {carry = (carry + 1) & 0xffffffff;}high[highindex] += (carry + mh);low[lowindex] &= 0xffffffff;high[lowindex] &= 0xffffffff;
}function NN_AssignZero(a, aindex, digits) {var tmpaindex = 0;if (digits != 0) {do {//*a++ = 0;//(*a) = 0;a[tmpaindex + aindex] = 0;//a++;tmpaindex++;digits--;if (digits == 0) {break;}} while (true);}
}function NN_Assign(a, aindex, b, bindex, digits) {var tmpaindex = 0;var tmpbindex = 0;if (digits != 0) {/*do {*a++ = *b++;}while(--digits);*/do {a[tmpaindex + aindex] = b[tmpbindex + bindex];//a++;//b++;tmpaindex++;tmpbindex++;digits--;if (digits == 0) {break;}} while (true);}
}function printfInts(title, data, len) {printfIntsIndex(title, data, 0, len);/*var i = 0;for (i = 0; i < len; i++) {console.log("%d %s %d", i, title == null ? "":title, data[i]);}*/
}function printfIntsIndex(title, data, index, len) {var i = 0;for (i = 0; i < len; i++) {console.log("%d %s %d", i, title == null ? "" : title, data[i + index]);}
}function NN_Digits(a, aindex, len) {var i = 0;for (i = len - 1; i >= 0; i--) {if (a[i + aindex] != 0) {return i + 1;}}return i;
}function BignumCmp(a, b) {var amax = a.length - 1;var bmax = b.length - 1;var i = (amax > bmax ? amax : bmax);var aval = 0;var bval = 0;while (i) {aval = i > amax ? 0 : a[i];bval = i > bmax ? 0 : b[i];if (((aval >> 16) & 0xffff) < ((bval >> 16) & 0xffff)) {return -1;}if (((aval >> 16) & 0xffff) > ((bval >> 16) & 0xffff)) {return 1;}if ((aval & 0xffff) < (bval & 0xffff)) {return -1;}if ((aval & 0xffff) > (bval & 0xffff)) {return 1;}i--;}return 0;
}function NN_Decode(bytesArray, len) {var bits = CalArrayBits(bytesArray, len);var i = 0;var j = 0;var outArray = new Array(parseInt((bits + 31) / 32));init_u32array(outArray, outArray.length);for (i = 0; i < outArray.length; i++) {j = bytesArray.length - (i + 1) * 4;//console.log("j = " + j);if (j >= 0) {outArray[i] = ((parseInt(bytesArray[j]) & 0xff) << 24) |((parseInt(bytesArray[j + 1]) & 0xff) << 16) |((parseInt(bytesArray[j + 2]) & 0xff) << 8) |((parseInt(bytesArray[j + 3]) & 0xff) << 0);} else {outArray[i] = 0;if (j + 1 >= 0) {outArray[i] |= ((parseInt(bytesArray[j + 1]) & 0xff) << 16);}if (j + 2 >= 0) {outArray[i] |= ((parseInt(bytesArray[j + 2]) & 0xff) << 8);}if (j + 3 >= 0) {outArray[i] |= ((parseInt(bytesArray[j + 3]) & 0xff) << 0);}}}return outArray;
}function CalArrayBits(arrayData, len) {var i = 0;var j = 0;for (i = 0; i < len; i++) {if (arrayData[i] != 0) {j = -1;break;}}if (j >= 0) {return 0;}for (j = 0; j < 8; j++) {if ((arrayData[i] & (0x80 >>> j)) != 0) {break;}}return 8 - j + (len - i - 1) * 8;
}function rsa_hex_to_array(hexStrIn) {var i = 0;var cnt = 0;var ele = 0;var bytesArray = null;cnt = 0;for (i = 0; i < hexStrIn.length; i++) {ele = hexStrIn.charCodeAt(i);if (ele >= 48 && ele < 48 + 10) {cnt++;}if (ele >= 65 && ele < 65 + 6) {cnt++;}if (ele >= 97 && ele < 97 + 6) {cnt++;}}bytesArray = new Uint8Array(parseInt((cnt + 1) / 2));cnt = 0;for (i = 0; i < hexStrIn.length; i++) {ele = hexStrIn.charCodeAt(i);if (ele >= 48 && ele < 48 + 10) {ele -= 48;cnt++;} else if (ele >= 65 && ele < 65 + 6) {ele = ele - 65 + 10;cnt++;} else if (ele >= 97 && ele < 97 + 6) {ele = ele - 97 + 10;cnt++;} else {continue;}if ((cnt % 2) == 1) {bytesArray[parseInt((cnt - 1) / 2)] = (ele << 4) & 0xF0;} else {bytesArray[parseInt((cnt - 1) / 2)] |= ele;}}return bytesArray;
}function rsa_hex_to_str(data, len) {var sha256_hex_digits = "0123456789abcdef";var output = new String();var i = 0;//console.log("ou1t = " + output);for (i = 0; i < len; i++) {// console.log("out = " + output);output += sha256_hex_digits.charAt((data[i] >>> 4) & 0x0f);output += sha256_hex_digits.charAt((data[i]) & 0x0f);}return output;
}module.exports = {rsa_set_key: rsa_set_key,rsa_pub_cal: rsa_pub_cal,rsa_pri_cal: rsa_pri_cal,rsa_hex_to_array: rsa_hex_to_array,rsa_hex_to_str: rsa_hex_to_str,rsa_pkcs1_pad:rsa_pkcs1_pad
}
测试代码:
如下在微信小程序中测试验证
var js_rsa = require('../../crypto/rsa.js');
testRsa() {var rsaCtx = null;var keyN = "BEC631E3067608D5065846573408462E4912D5EA343F0FB45DB7F2A1673D5A6D070DE518EBD4420A44E32188313A8B3321FFFC981FEA277BA833E224B9B21A036CE102047DFCBB0F4907EB670C9603E9FD9753681AA74873F47765B03B57E5EB184F4BAB576E4C03FAC8261A560B3EC79EBAFA92DE644362C8D79A7AD858F06CD3DA850ED467F0168B2FB49455A01CCE950ED110C78A90163B315D9C96368AE78F75B0813BEA33B50DFCDCF61D14AF8EB1313A53E3F90C43324EFB315D1FEC64851517C0068257953EE066F305410B2D729753E8D0F7F6D7089B89986B3A9A6109BCB66D4D1FFFF1DFFB347CE0C04019473FC88FA94C4C629A25460BFA900291";var keyD = "6D26C6FA470317D0927DC559358B1A647728D0BDDCC0CC027DB0B6A10489C50826861BB363932169F0BA27C05DB24A5CAA3265DAC03FDFF14F6EC8100D334AD0F4E5D49AAF5EFFC4221BE6E321FF5F23ED153D028E6571FDEE3CB630DBF351B86E43485F337A07022BE5826F85159008F4D7B4707DCFCE02623981C891AA697C4D746DD007330F697F8739392E9001D4FC2993C5E78D1A283C38AAED24EF4C672A1C4E72B2781759080CAE8383EEB69C8BC232360850FEBEF9D862DBC7225A9FE13F98F6BD072C7A027DEA9F9C9CDAB4D3F5F37B03B2375DA9BEF8CF1AD3CCB4C24B236685DDC82F10BA9584FA9A34D545B528B213675E969D7CA3839418AB95";var keyE = "010001";var txt = "00888888889999999999999AAAAAAAAABBBBBBBBCEDFFFFFFFFFFFFFFFFFFFFFFFFF966666666666666666666666666666666666666666666666666633333333333333333333333333333333300000000000000000000000666EEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFDDDDDDDDDDDDBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA88888888644444444444777777777777777799999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999555555555555555555555555555555555555555522222222222222222222222222222222222222";var result, result2;var tmpdata = null;rsaCtx = js_rsa.rsa_set_key(js_rsa.rsa_hex_to_array(keyN), js_rsa.rsa_hex_to_array(keyE), js_rsa.rsa_hex_to_array(keyD));result = js_rsa.rsa_pub_cal(rsaCtx, js_rsa.rsa_hex_to_array(txt));console.log("rsa_pub_cal:" + js_rsa.rsa_hex_to_str(result, result.length));result2 = js_rsa.rsa_pri_cal(rsaCtx, result);console.log("rsa_pri_cal:" + js_rsa.rsa_hex_to_str(result2, result2.length));/* 下面的用pkcs1填充然后公玥计算,可以在后台用对应的私玥解密出来 */tmpdata = js_rsa.rsa_pkcs1_pad(js_rsa.rsa_hex_to_array("1122334455667788"), 2, rsaCtx.keybits);result = js_rsa.rsa_pub_cal(rsaCtx, tmpdata);console.log("rsa_pub_cal:" + js_rsa.rsa_hex_to_str(result, result.length));result2 = js_rsa.rsa_pri_cal(rsaCtx, result);console.log("rsa_pri_cal:" + js_rsa.rsa_hex_to_str(result2, result2.length));},
测试结果:
rsa_pub_cal:2fac299b8f780e12a331a73ca61551deb3cd41127d76d5c855624eb6d02eac9581be481fec0ec3c882e1cb26de31dffa19a689cd36a5255021fc44ab3399385f91db7352701bca8f1955237085ef2e0d216831653367799cddaf8c4b77611287fedfcc93de93d3c28461d29d609322f1b1d1b4543d1cc2921b50253fd1da15f9174a94ff8cb70cab180d56d00dd4f28e3a914abc28f770623af2eed11c560a26fe1187050038da28ad897068373b5bdfe14fb44905fcdc0cbeefde21a155ecf238423a2c967b710cbab39a235a6385c285535707c20bab1ae7601def49959cd42aa700389423fdcf17f2c42a00f2b1da8320586d24ef5d5dfe92cc203047020b
rsa_pri_cal:00888888889999999999999aaaaaaaaabbbbbbbbcedfffffffffffffffffffffffff966666666666666666666666666666666666666666666666666633333333333333333333333333333333300000000000000000000000666eeeeeeeeeeeeeeeeeeeeeefffffffffffffffffffddddddddddddbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaa88888888644444444444777777777777777799999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999555555555555555555555555555555555555555522222222222222222222222222222222222222
rsa_pub_cal:0c0b82faa9ea15227d77e043db0467261bf4957450ff3342a51f0ebc41112a0a62f509c4d8c6d6554e4d95997f89f6b4ff6ea728287bd6324f9989cdbfe9057740184eca47cb1d07bb082e8e09f4fb9e6befba4765b06fc0ddf4b9ddfa744fde3404ef5106bd772373a41bbc463c63808c972790bed8991089f62ee9f20ab638d177c0abe9b0b706639e782186515418a1bc743513051cd562a8b081b9d25b70eea813a7a48ede372833723fe4bbf7d8b4b20dc1457ae9277f4f4ff4c35873933bdb5eb99fc1bf9b1ec37a3e0ee542eadbdf89340dc90888747b221a35a43107fcdd2eeed2b9962277032b711d3713f7a1ce63318bae02ca462584850a182b32
rsa_pri_cal:0002c30f4202dcace6f9d5e2ff47c9014a4f8c7ca2dcd0fd54ee7d3eead63eb67ca9b76980a7b5d1cd72cab7c56e9aa142b59a79dcf07e5d1189ee09727b5ca372697be5cf6fda20a7cefab1c558c1a6e57609773c0355f407198250d252a4f8d01785f9271e9d160aae2ba2dc2314714fb4cca0b20320b6329224c5ba154b086d479ccd27353d9d9eaa48f5e1743b2fd44e0f46b85d894a41e239c696f1e9a71a22c83c9f69ce1541ebcd1106446c1f5c5b074ec5b580f4263930ffdf9bbdc7bf1cd6d86971744173a15d3eefbe7f1ab8c5363c5d62eccce5c404c3cb954a7f7c09a61dd75e56dcef2fbc98593dbe52f0e317ee5a5f65001122334455667788