@smt-lib/rsa

解释: 在小程序开发中,没有window的概念,导致市面上很多绑定DOM或者BOM的三方库无法使用,swan-crypto是官方提供的加解密库。

Usage no npm install needed!

<script type="module">
  import smtLibRsa from 'https://cdn.skypack.dev/@smt-lib/rsa';
</script>

README

解释: 在小程序开发中,没有window的概念,导致市面上很多绑定DOM或者BOM的三方库无法使用,swan-crypto是官方提供的加解密库。

方法 RSAParser

属性名 类型 必填 默认值 说明
publicKey String 公钥
privateKey String 私钥

各部分代码示例

const RSAParser = require('RSAParser');
const parser = new RSAParser({
    publicKey: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhSzPPnFn41iaz+t4tI4kbaXNu
NFOsI8hFeCYtlwPFKRbETHbBS10bMvUbOWLFtRgZV3L924GQ9orbomEmJ1nWyaSO
8iBbZAyiWUP5PJJh/b9kHj1MMwG712bGfYYPdjkRprNpzU9w4UBzUMKKUoHU4c/G
bb4XeBK9LNTPWQL4YwIDAQAB
-----END PUBLIC KEY-----
`,
     privateKey: `-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOFLM8+cWfjWJrP6
3i0jiRtpc240U6wjyEV4Ji2XA8UpFsRMdsFLXRsy9Rs5YsW1GBlXcv3bgZD2itui
YSYnWdbJpI7yIFtkDKJZQ/k8kmH9v2QePUwzAbvXZsZ9hg92ORGms2nNT3DhQHNQ
wopSgdThz8Ztvhd4Er0s1M9ZAvhjAgMBAAECgYEAxwNLTUXsJGfn4Gzm/jC52MEZ
+mu2zgT90IAGGZeg+PUG63gwHyeXo4MsCVRz7/m8xAX/ykew+IEQwFt8Pdvc+rrs
5yml4gOBPfhpau5QaI75xNjnyH7UA3mbRCZeyZrvuKqtY/f8pCgzy3EBWnRpkcsq
eE6bsOQrD45mltr+0QECQQDynvhKEh+hD5xBpF/DIP8Fp6fizexHdA6+aZT/gLaF
A4XgZ9HEDDBhvNdadyYUNOLWhkxRHv6CkT5azfLXsJEhAkEA7begtbBCDXDf1+DR
h3j2S8zcv6+utYgcpjvxZqjbPi6UIWXLxI80PIwQ0uouHCUMjikBA6VX9vTbw9TZ
/IelAwJBAKI3W7baiz86mrTg3A4w/5GeWQexuurDVCBHo5F5U493nYk+oOe9ZpPS
mQIpa9JS0d+xB1GtsWlHBzPbQySnL0ECQA/btCjqvT1QTl6EbPXwp92eqQtQmQMb
NW4RiaUjlpyrVs5zkAho1T9EyMqJPNI71n6VVa/8k8WxyAdkZ7ZlBikCQEkNe1+s
AKnh+AFGCJ+6WAq1J2RuIgcA6bVL3ip7F2NHdE+N+tR9JqWw3JNCweWmAlzKIGs6
eKSVD5egzKaLXss=
-----END PRIVATE KEY-----`
});

const secretContent = parser.encrypt(`i
            love
            baidu`);

console.log('secretContentsecretContent::', secretContent);

const publicContent = parser.decrypt(secretContent);

console.log('publicContentpublicContent::', publicContent);

核心算法原理:

/**
 * @file rsa加密库的基本远离
 */
(function () {

    const gcd = (a, b) => {
        return a % b ? gcd(b, a % b) : b;
    };

    // 找两个质数
    const P = 3;
    const Q = 5;

    // "010001"
    // 第二步,算N的欧拉函数 --- M
    const N = P * Q;
    const M = (P - 1) * (Q - 1);

    // 第三步,在1~M之间,选一个与M互质的数
    let e = 0;
    // 选最小的就行
    for (let i = 2; i < M; i++) {
        // 互质
        if (gcd(i, M) === 1) {
            e = i;
            break;
        }
    }

    // 第四步,算出一个整数D,是的E * D 除以M的余数为1
    // 换成公式就是:D * E - Y * M = 1;(其中D与Y都是变量,E与M均已算出来了)
    const gcdEx = (a, b) => {
        if (b === 0) {
            return {
                x: 1,
                y: 0
            };
        }

        const point = gcdEx(b, a % b);
        return {
            x: point.y,
            y: point.x - Math.floor(a / b) * point.y
        };
    };

    // 求出来了D
    const d = gcdEx(e, M).x;

    // 公钥对
    const pubKey = [N, e];
    // 私钥对
    const privateKey = [N, d];
 
    // 测试内容
    let testcontent = 10;
    // 加密: 内容 ^ e % N = 加密内容
    const secreteContent = Math.pow(testcontent, e) % N;
    console.log('secreteContent:::', secreteContent);

    // 解密: 加密内容 ^ d % N = 内容
    let publicContent = Math.pow(secreteContent, d) % N;
    console.log('public content:::', publicContent);
})();