Skip to content
目录

RSA加解密

为了避免因明文传输带来的不完全问题,所有敏感信息均需加密处理,要查看明文则需要解密处理,涉及RTSP地址(包含密码)、海康安防综合管理平台的appKey和appSecret等。这里,我们统一采用 RSA 加解密算法。如果您使用 js/ts 语言开发,推荐使用 jsencrypt 库。注意:jsencrypt库存在问题,如果加密文本过长可能会出现“Message too long for RSA”错误,解决方法参考【这里】

密钥

密钥使用如下固定密钥,使用公钥加密,使用私钥解密。

公钥:

txt
-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgG2CKPoayirsqic3eooiV8hm7Q/s
G4QHk1+la7fExuqvb4KK9JFb4YrkKURpZ6zZUUGlV+lKX3cDaW6qTCpQ7WCw7+Nt
FS1HTa3Jx32U0Pk4/UBwx1bvppeWnMtoN8FA5N4n+ofs+mSrHQu4qMsKEVNxqYlR
wycB/jxkmF+oDTDRAgMBAAE=
-----END PUBLIC KEY-----

私钥:

txt
-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgG2CKPoayirsqic3eooiV8hm7Q/sG4QHk1+la7fExuqvb4KK9JFb
4YrkKURpZ6zZUUGlV+lKX3cDaW6qTCpQ7WCw7+NtFS1HTa3Jx32U0Pk4/UBwx1bv
ppeWnMtoN8FA5N4n+ofs+mSrHQu4qMsKEVNxqYlRwycB/jxkmF+oDTDRAgMBAAEC
gYAMR506tohXGeTWsvTtyn4Xfds1ft9zBbpz7kPO/qTjqjqR4+0a47e98GnkPwGe
M1xWRSk/gtSDrwFCpJwX3q1PlSBg9IZnkKWcU+pnkwaVajeTr2mViBDk6ORtCHk8
4Y7YiMyhxT301UHkfZ2BUt6an7N3pM5UEzuZnBdENQXaAQJBAMvNeAePLvaqBmiq
nRqF1I0dem7MAdIYiHfExExnUDpHQAgqQU7o0j4BmmAj1GTf4g6T7INrxkH8gviR
6SfXBfECQQCJjjH1Ilz1gXJyeEQXAlu3lC+Ft5S8WfJ+ayMehZqx+hm65EkzGdM+
/uMZHtSQXVFCRFlAh8R2TtGkkPSFyHjhAkAAlBK1IsjlVlIyVdmgS6TwyZahXd7b
c8pfXKWZ+ekWYUFjRItu5+ZA2sxPXYqqxp/jnrPbI6EqascMYY2h2VBhAkA152Uo
XMj05D9HIF3+bkwmyok860376Xufkrh2c4DFke6XUHJm9g3UN+oio/REhm0bfNFE
+m9AtW5uAOfxrTfBAkAx/2KoEicPt9Rkt49Yol51onw8NCiHayeTty5iFqxBMIBQ
NxwTtWeRM0Ulz7HjBnB1EI40KIgWPuO4xCpazCDH
-----END RSA PRIVATE KEY-----

js版加解密算法

以下代码仅供参考,未处理“Message too long for RSA”问题,解决方法参考【这里】

js
import JSEncrypt from 'jsencrypt';

const b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const b64pad = "=";
JSEncrypt.prototype.encryptLong2 = function (string) {
    const k = this.getKey();
    try {
        const lt = "";
        let ct = "";
        //RSA每次加密117bytes,需要辅助方法判断字符串截取位置
        //1.获取字符串截取点
        const bytes = new Array();
        bytes.push(0);
        let byteNo = 0;
        let len, c;
        // eslint-disable-next-line prefer-const
        len = string.length;
        let temp = 0;
        // eslint-disable-next-line no-var
        for (var i = 0; i < len; i++) {
            c = string.charCodeAt(i);
            if (c >= 0x010000 && c <= 0x10FFFF) {
                byteNo += 4;
            } else if (c >= 0x000800 && c <= 0x00FFFF) {
                byteNo += 3;
            } else if (c >= 0x000080 && c <= 0x0007FF) {
                byteNo += 2;
            } else {
                byteNo += 1;
            }
            if ((byteNo % 117) >= 114 || (byteNo % 117) == 0) {
                if (byteNo - temp >= 114) {
                    bytes.push(i);
                    temp = byteNo;
                }
            }
        }
        //2.截取字符串并分段加密
        if (bytes.length > 1) {
            // eslint-disable-next-line no-var
            for (var i = 0; i < bytes.length - 1; i++) {
                // eslint-disable-next-line no-var
                var str;
                if (i == 0) {
                    str = string.substring(0, bytes[i + 1] + 1);
                } else {
                    str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
                }
                const t1 = k.encrypt(str);
                ct += addPreZero(t1, 256);
            }
            ;
            if (bytes[bytes.length - 1] != string.length - 1) {
                const lastStr = string.substring(bytes[bytes.length - 1] + 1);
                const rsaStr = k.encrypt(lastStr)
                ct += addPreZero(rsaStr, 256);
            }
            //console.log("加密完的数据:"+ct);
            return hex2b64(ct);
        }
        const t = k.encrypt(string);
        const y = hex2b64(t);
        return y;
    } catch (ex) {
        return false;
    }
}

JSEncrypt.prototype.decryptLong2 = function (string) {
    const k = this.getKey();
    // var maxLength = ((k.n.bitLength()+7)>>3);
    const MAX_DECRYPT_BLOCK = 128;
    try {
        let ct = "";
        let t1;
        let bufTmp;
        let hexTmp;
        const str = b64tohex(string);
        const buf = hexToBytes(str);
        const inputLen = buf.length;
        //开始长度
        let offSet = 0;
        //结束长度
        let endOffSet = MAX_DECRYPT_BLOCK;

        //分段解密
        // console.log(inputLen + "----" + offSet)
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                bufTmp = buf.slice(offSet, endOffSet);
                hexTmp = bytesToHex(bufTmp);
                t1 = k.decrypt(hexTmp);
                ct += t1;

            } else {
                bufTmp = buf.slice(offSet, inputLen);
                hexTmp = bytesToHex(bufTmp);
                t1 = k.decrypt(hexTmp);
                ct += t1;

            }
            offSet += MAX_DECRYPT_BLOCK;
            endOffSet += MAX_DECRYPT_BLOCK;
        }
        return ct;
    } catch (ex) {
        return false;
    }
}

//  在JsEncrypt原型上写了分段加密方法 encryptLong 使用时替换encrypt方法即可
function hex2b64(h) {
    let i;
    let c;
    let ret = "";
    for (i = 0; i + 3 <= h.length; i += 3) {
        c = parseInt(h.substring(i, i + 3), 16);
        ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
    }
    if (i + 1 == h.length) {
        c = parseInt(h.substring(i, i + 1), 16);
        ret += b64map.charAt(c << 2);
    }
    else if (i + 2 == h.length) {
        c = parseInt(h.substring(i, i + 2), 16);
        ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
    }
    while ((ret.length & 3) > 0) ret += b64pad;
    return ret;
}
function hexToBytes(hex) {
    for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.substr(c, 2), 16));
    return bytes;
}
function bytesToHex(bytes) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
    }
    return hex.join("");
}
function b64tohex(str) {
    var bin = '';
    try {//旧版本的nodejs没有atob这个方法
        bin = atob(str.replace(/[ \r\n]+$/, ""));
    }
    catch {
        try {
            bin = Buffer.from(str.replace(/[ \r\n]+$/, ""), 'base64').toString('latin1');
        }
        catch { }
    }
    var hex = [];
    for (var i = 0; i < bin.length; ++i) {
        var tmp = bin.charCodeAt(i).toString(16);
        if (tmp.length === 1) tmp = "0" + tmp;
        hex[hex.length] = tmp;
    }
    return hex.join("");
}
function addPreZero(num, length) {
    var t = (num + '').length,
        s = '';
    for (var i = 0; i < length - t; i++) {
        s += '0';
    }

    return s + num;
}


const publicKey = `-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgG2CKPoayirsqic3eooiV8hm7Q/s
G4QHk1+la7fExuqvb4KK9JFb4YrkKURpZ6zZUUGlV+lKX3cDaW6qTCpQ7WCw7+Nt
FS1HTa3Jx32U0Pk4/UBwx1bvppeWnMtoN8FA5N4n+ofs+mSrHQu4qMsKEVNxqYlR
wycB/jxkmF+oDTDRAgMBAAE=
-----END PUBLIC KEY-----`;

const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgG2CKPoayirsqic3eooiV8hm7Q/sG4QHk1+la7fExuqvb4KK9JFb
4YrkKURpZ6zZUUGlV+lKX3cDaW6qTCpQ7WCw7+NtFS1HTa3Jx32U0Pk4/UBwx1bv
ppeWnMtoN8FA5N4n+ofs+mSrHQu4qMsKEVNxqYlRwycB/jxkmF+oDTDRAgMBAAEC
gYAMR506tohXGeTWsvTtyn4Xfds1ft9zBbpz7kPO/qTjqjqR4+0a47e98GnkPwGe
M1xWRSk/gtSDrwFCpJwX3q1PlSBg9IZnkKWcU+pnkwaVajeTr2mViBDk6ORtCHk8
4Y7YiMyhxT301UHkfZ2BUt6an7N3pM5UEzuZnBdENQXaAQJBAMvNeAePLvaqBmiq
nRqF1I0dem7MAdIYiHfExExnUDpHQAgqQU7o0j4BmmAj1GTf4g6T7INrxkH8gviR
6SfXBfECQQCJjjH1Ilz1gXJyeEQXAlu3lC+Ft5S8WfJ+ayMehZqx+hm65EkzGdM+
/uMZHtSQXVFCRFlAh8R2TtGkkPSFyHjhAkAAlBK1IsjlVlIyVdmgS6TwyZahXd7b
c8pfXKWZ+ekWYUFjRItu5+ZA2sxPXYqqxp/jnrPbI6EqascMYY2h2VBhAkA152Uo
XMj05D9HIF3+bkwmyok860376Xufkrh2c4DFke6XUHJm9g3UN+oio/REhm0bfNFE
+m9AtW5uAOfxrTfBAkAx/2KoEicPt9Rkt49Yol51onw8NCiHayeTty5iFqxBMIBQ
NxwTtWeRM0Ulz7HjBnB1EI40KIgWPuO4xCpazCDH
-----END RSA PRIVATE KEY-----`;
/**
 * RSA加密
 * @param {string} text 明文
 */
export function encode(text) {
    if (!text) return '';
    let rsa = new JSEncrypt();
    rsa.setPublicKey(publicKey);
    return rsa.encryptLong2(text) || text;
}
/**
 * RSA解密
 * @param {string} text 密文
 */
export function decode(text) {
    if (!text) return '';
    let rsa = new JSEncrypt();
    rsa.setPrivateKey(privateKey);
    return rsa.decryptLong2(text) || text;
}

技术支持:13352865103(柯工,微信同号);18688783852(柯工)