引用上文:
CSDNhttps://mp.csdn.net/mp_blog/creation/editor/134857857
剖析:
var bitsPerDigit=16; // 每个数组元素可以表示的二进制位数
// 数组复制函数,将源数组部分复制到目标数组的指定位置
function arrayCopy(src, srcStart, dest, destStart, n) {
var m = Math.min(srcStart + n, src.length);
for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
dest[j] = src[i];
}
}
var maxDigitVal = 65535; // 数字最大值(16位,即2的16次方减一)
var biRadixBits = 16; // 基数位数(二进制)
// 多个函数与算法中用到的变量和计算方式,例如乘法、乘方、左移等,略去具体说明
// 返回大整数的十六进制字符串
function biToHex(x) {
var result = "";
var n = biHighIndex(x); // 获取有效位
for (var i = biHighIndex(x); i > -1; --i) {
result += digitToHex(x.digits[i]);
}
return result;
}
// RSA公钥对的构造函数
function RSAKeyPair(encryptionExponent, decryptionExponent, modulus, keylen) {
// 设置公钥、私钥和模数为大整数BigInt
this.e = biFromHex(encryptionExponent);
this.d = biFromHex(decryptionExponent);
this.m = biFromHex(modulus);
// 如果没有提供密钥长度,则通过模数的位数计算,每个chunk的大小(二进制字节单位)
this.chunkSize = (keylen) ? keylen / 8 : 2 * biHighIndex(this.m);
this.radix = 16; // 设置输出的基数(十六进制)
this.barrett = new BarrettMu(this.m); // 用于优化模逆计算的BarrettMu对象
}
// 大整数BigInt的构造函数,如果传入true,则digits不初始化,否则初始化为零数组
function BigInt(flag) {
if (typeof flag == "boolean" && flag == true) {
this.digits = null;
} else {
this.digits = ZERO_ARRAY.slice(0);
}
this.isNeg = false; // 表示数字的符号,默认为非负
}
// 设置全局的最大数字位数和相应的零数组、bigZero、bigOne等的初始化
function setMaxDigits(value) {
maxDigits = value;
ZERO_ARRAY = new Array(maxDigits);
for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
bigZero = new BigInt();
bigOne = new BigInt();
bigOne.digits[0] = 1;
}
// 被RSA加密函数使用的内部函数,略去具体说明
// RSA加密的实现函数
function encryptedString(key, s, pad, encoding) {
// ...详细的加密处理...
// 使用公钥中的指数e对数据进行加密,最终返回加密字符串
}
// rsa函数封装了创建密钥、设置位数和执行加密操作
function rsa(arg) {
setMaxDigits(130); // 设置最大位数
var PublicExponent = "10001"; // 公开指数部分,一般为65537
var modulus = "..."; // 模数,这里因篇幅而缩略
var key = new RSAKeyPair(PublicExponent, "", modulus); // 生成RSA公钥对
return encryptedString(key, arg); // 返回加密后的字符串
}
console.log(rsa("输入你的密码")) // 执行RSA加密,并打印加密后的结果