// utils/base64js
export default (function(r) {
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = r()
} else {
if (typeof define === "function" && define.amd) {
define([], r)
} else {
var e;
if (typeof window !== "undefined") {
e = window
} else {
if (typeof global !== "undefined") {
e = global
} else {
if (typeof self !== "undefined") {
e = self
} else {
e = this
}
}
}
e.base64js = r()
}
}
})(function() {
var r, e, t;
return function r(e, t, n) {
function o(i, a) {
if (!t[i]) {
if (!e[i]) {
var u = typeof require == "function" && require;
if (!a && u) {
return u(i, !0)
}
if (f) {
return f(i, !0)
}
var d = new Error("Не удалось найти модуль '" + i + "'");
throw d.code = "MODULE_NOT_FOUND", d
}
var c = t[i] = {
exports: {}
};
e[i][0].call(c.exports, function(r) {
var t = e[i][1][r];
return o(t ? t : r)
}, c, c.exports, r, e, t, n)
}
return t[i].exports
}
``` var f = typeof require == "function" && require;
for (var i = 0; i < n.length; i++) {
o(n[i])
}
return o
}({
"/": [function(r, e, t) {
t.byteLength = c;
t.toByteArray = v;
t.fromByteArray = s;
var n = [];
var o = [];
var f = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
var i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (var a = 0, u = i.length; a < u; ++a) {
n[a] = i[a];
o[i.charCodeAt(a)] = a
}
o["-".charCodeAt(0)] = 62;
o["_".charCodeAt(0)] = 63;
function d(r) {
var e = r.length;
if (e % 4 > 0) {
throw new Error("Недопустимая строка. Длина должна быть кратна 4")
}
return r[e - 2] === "=" ? 2 : r[e - 1] === "=" ? 1 : 0
}```markdown
Функция `c(r)` {
возвращаемое значение = длина(r) * 3 / 4 - d(r)
}
``````markdown
функция `v(r)` {
var e, t, n, i, a;
var u = длина(r);
i = d(r);
a = новый f(длина(r) * 3 / 4 - i);
t = i > 0 ? длина(r) - 4 : длина(r);
var c = 0;
для (e = 0; e < t; e += 4) {
n = o[кодASCII(r, e)] << 18 | o[кодASCII(r, e + 1)] << 12 | o[кодASCII(r, e + 2)] << 6 | o[кодASCII(r, e + 3)];
a[c++] = n >> 16 & 255;
a[c++] = n >> 8 & 255;
a[c++] = n & 255
}
если (i === 2) {
n = o[кодASCII(r, e)] << 2 | o[кодASCII(r, e + 1)] >> 4;
a[c++] = n & 255
} иначе {
если (i === 1) {
n = o[кодASCII(r, e)] << 10 | o[кодASCII(r, e + 1)] << 4 | o[кодASCII(r, e + 2)] >> 2;
a[c++] = n >> 8 & 255;
a[c++] = n & 255
}
}
возвращаемое значение = a
}
``````js
// utils/sm4.js
функция `SM4Util(secretKey)` {
let base64js = require("./base64.js");
this.secretKey = secretKey;
this.iv = "";
this.decryptData_ECB = функция(data) {
var byteEcb = base64js.toByteArray(data);
// строка преобразуется в байты
var key = this.stringToByte(this.secretKey);
var sm4 = new SM4();
// выполнение шифрования sm
var plain = sm4.decrypt_ecb(key, byteEcb);
``````md
// Возвращает зашифрованный текст
this.encryptData_CBC = function(data) {
var inputBytes = this.stringToByte(data);
var key = this.stringToByte(this.secretKey);
var iv = this.stringToByte(this.iv);
var sm4 = new SM4();
var cipher = sm4.encrypt_cbc(key, iv, inputBytes);
// Преобразование байтов в base64 строку.
var cipherText = base64js.fromByteArray(cipher);
if (cipherText != null && cipherText.trim().length > 0) {
cipherText.replace(/(\s*|\t|\r|\n)/g, "");
}
return cipherText;
}
// Возвращает зашифрованный текст
this.encryptData_ECB = function(data) {
var inputBytes = this.stringToByte(data);
var key = this.stringToByte(this.secretKey);
var sm4 = new SM4();
var cipher = sm4.encrypt_ecb(key, inputBytes);
// Преобразование байтов в base64 строку.
var cipherText = base64js.fromByteArray(cipher);
if (cipherText != null && cipherText.trim().length > 0) {
cipherText.replace(/(\s*|\t|\r|\n)/g, "");
}
return cipherText;
}
// Возвращает расшифрованный текст
this.decryptData_CBC = function(data) {
var inputBytes = base64js.toByteArray(data);
var key = this.stringToByte(this.secretKey);
var iv = this.stringToByte(this.iv);
var sm4 = new SM4();
var plain = sm4.decrypt_cbc(key, iv, inputBytes);
// Преобразование байтов в строку с помощью метода Hex.encode
return Hex.bytesToUtf8Str(plain);
}
this.stringToByte = function(str) {
var bytes = new Array();
var len, c;
len = str.length;
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i);
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0);
bytes.push(((c >> 12) & 0x3F) | 0x80);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0);
bytes.push(((c >> 6) & 0x3F) | 0x80);
bytes.push((c & 0x3F) | 0x80);
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0);
bytes.push((c & 0x3F) | 0x80);
} else {
bytes.push(c & 0xFF);
}
}
return bytes;
}```markdown
}
function SM4() {```markdown
this.sbox = new Array(
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
);
this.fk = new Array(0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc);
this.ck = new Array(
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
);
```SM4.prototype = {
expandKey: function(key) {
var k = new Array(36);
var mk = byteArrayToIntArray(key);
k[0] = mk[0] ^ this.fk[0];
k[1] = mk[1] ^ this.fk[1];
k[2] = mk[2] ^ this.fk[2];
k[3] = mk[3] ^ this.fk[3];
var rk = new Array(32);
for (var i = 0; i < 32; i++) {
k[(i + 4)] = (k[i] ^ this.T1(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ this.ck[i]));
rk[i] = k[(i + 4)];
}
return rk;
},
T1: function(ta) {
var rk = 0;
var b = new Array(4);
var a = intToByte(ta);
b[0] = this.sbox[a[0] & 0xFF];
b[1] = this.sbox[a[1] & 0xFF];
b[2] = this.sbox[a[2] & 0xFF];
b[3] = this.sbox[a[3] & 0xFF];
var bint = byteToInt(b, 0);
var rk = bint ^ (bint << 13 | (bint >>> (32 - 13))) ^ (bint << 23 | (bint >>> (32 - 23)));
return rk;
},
one_encrypt: function(rk, data) {
var x = new Array(36);
x[0] = byteToInt(data, 0);
x[1] = byteToInt(data, 4);
x[2] = byteToInt(data, 8);
x[3] = byteToInt(data, 12);
for (var i = 0; i < 32; i++) {
x[(i + 4)] = x[i] ^ this.T0(x[(i + 1)] ^ x[(i + 2)] ^ x[(i + 3)] ^ rk[i]);
}
var tmpx = new Array(4);
for (var i = 35; i >= 32; i--) {
tmpx[35 - i] = x[i];
}
var xbyte = intArrayToByteArray(tmpx);
}
};```markdown
var ret = null;
if (mode == 1) { // Заполнение
var p = 16 - input.length % 16;
ret = new Array(input.length + p);
arrayCopy(input, 0, ret, 0, input.length);
for (var i = 0; i < p; i++) {
ret[input.length + i] = p;
}
} else { // Удаление заполнения
var p = input[input.length - 1];
ret = new Array(input.length - p);
arrayCopy(input, 0, ret, 0, input.length - p);
}
return ret;
},
encrypt_ecb: function(key, data) {
if (key == undefined || key == null || key.length % 16 != 0) {
return null;
}
if (data == undefined || data == null || data.length <= 0) {
return null;
}
var rk = this.expandKey(key);
var blockLen = 16;
var loop = parseInt(data.length / blockLen); // Обратите внимание, что деление не должно быть точным, иначе будет ошибка
var cipher = new Array((loop + 1) * blockLen);
var tmp = new Array(blockLen);
var oneCipher = null;
for (var i = 0; i < loop; i++) {
arrayCopy(data, i * blockLen, tmp, 0, blockLen);
oneCipher = this.one_encrypt(rk, tmp);
arrayCopy(oneCipher, 0, cipher, i * blockLen, blockLen);
}
var lessData = new Array(data.length % blockLen);
if (lessData.length > 0) {
arrayCopy(data, loop * blockLen, lessData, 0, data.length % blockLen);
}
var padding = this.pkcs7padding(lessData, 1);
oneCipher = this.one_encrypt(rk, padding);
arrayCopy(oneCipher, 0, cipher, loop * blockLen, blockLen);
``` return cipher;
},
decrypt_ecb: function(key, data) {
if (key == undefined || key == null || key.length % 16 != 0) {
return null;
}
if (data == undefined || data == null || data.length % 16 != 0) {
return null;
}
var rk = this.expandKey(key);
var nrk = new Array(32);
for (var i = 0; i < rk.length; i++) {
nrk[i] = rk[32 - i - 1];
}
var blockLen = 16;
var loop = data.length / blockLen - 1;
var tmp = new Array(blockLen);
var onePlain = null;
var plain = null;
// Сначала расшифровываем последнюю часть, чтобы определить длину данных
arrayCopy(data, loop * blockLen, tmp, 0, blockLen);
onePlain = this.one_encrypt(nrk, tmp);
var lastPart = this.pkcs7padding(onePlain, 0);
}```markdown
// Расшифровка оставшихся данных
for (var i = 0; i < loop; i++) {
arrayCopy(data, i * blockLen, tmp, 0, blockLen);
onePlain = this.one_encrypt(nrk, tmp);
arrayCopy(onePlain, 0, plain, i * blockLen, blockLen);
}
return plain;
},
encrypt_cbc: function(key, iv, data) {
if (key == undefined || key == null || key.length % 16 != 0) {
return null;
}
if (data == undefined || data == null || data.length <= 0) {
return null;
}
if (iv == undefined || iv == null || iv.length % 16 != 0) {
return null;
}
var rk = this.expandKey(key);
var blockLen = 16;
var loop = parseInt(data.length / blockLen); // Обратите внимание, что деление не всегда целое, поэтому результат нужно округлять
var cipher = new Array((loop + 1) * blockLen);
var tmp = new Array(blockLen);
for (var i = 0; i < loop; i++) {
arrayCopy(data, i * blockLen, tmp, 0, blockLen);
for (var j = 0; j < blockLen; j++) {
tmp[j] = tmp[j] ^ iv[j];
}
iv = this.one_encrypt(rk, tmp);
arrayCopy(iv, 0, cipher, i * blockLen, blockLen);
}
var lessData = new Array(data.length % blockLen);
if (lessData.length > 0) {
arrayCopy(data, loop * blockLen, lessData, 0, data.length % blockLen);
}
var padding = this.pkcs7padding(lessData, 1);
for (var i = 0; i < blockLen; i++) {
padding[i] = padding[i] ^ iv[i];
}
iv = this.one_encrypt(rk, padding);
arrayCopy(iv, 0, cipher, loop * blockLen, blockLen);
return cipher;
},
decrypt_cbc: function(key, iv, data) {
if (key == undefined || key == null || key.length % 16 != 0) {
return null;
}
if (data == undefined || data == null || data.length % 16 != 0) {
return null;
}
if (iv == undefined || iv == null || iv.length % 16 != 0) {
return null;
}
var rk = this.expandKey(key);
var nrk = new Array(32);
for (var i = 0; i < rk.length; i++) {
nrk[i] = rk[32 - i - 1];
}
var blockLen = 16;
var loop = data.length / blockLen;
var tmp = new Array(blockLen);
var onePlain = null;
var plain = null;
``````markdown
// Расшифровка
plain = new Array(data.length);
for (var i = 0; i < loop; i++) {
arrayCopy(data, i * blockLen, tmp, 0, blockLen);
onePlain = this.one_encrypt(nrk, tmp);
for (var j = 0; j < blockLen; j++) {
onePlain[j] = onePlain[j] ^ iv[j];
}
arrayCopy(tmp, 0, iv, 0, blockLen);
arrayCopy(onePlain, 0, plain, i * blockLen, blockLen);
}
```
```markdown
// Удалить заполнение, определить длину данных
var lastPart = this.pkcs7padding(onePlain, 0);
var realPlain = new Array(plain.length - blockLen + lastPart.length);
arrayCopy(plain, 0, realPlain, 0, plain.length - blockLen);
arrayCopy(lastPart, 0, realPlain, plain.length - blockLen, lastPart.length);
return realPlain;
}
}
function Hex() {
}
Hex.encode = function(b, pos, len) {
var hexCh = new Array(len * 2);
var hexCode = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
for (var i = pos, j = 0; i < len + pos; i++, j++) {
hexCh[j] = hexCode[(b[i] & 0xFF) >> 4];
hexCh[++j] = hexCode[(b[i] & 0x0F)];
}
return hexCh.join('');
}
Hex.decode = function(hex) {
if (hex == null || hex == '') {
return null;
}
if (hex.length % 2 != 0) {
return null;
}
var ascLen = hex.length / 2;
var hexCh = this.toCharCodeArray(hex);
var asc = new Array(ascLen);
for (var i = 0; i < ascLen; i++) {
if (hexCh[2 * i] >= 0x30 && hexCh[2 * i] <= 0x39) {
asc[i] = ((hexCh[2 * i] - 0x30) << 4);
} else if (hexCh[2 * i] >= 0x41 && hexCh[2 * i] <= 0x46) { //A-F : 0x41-0x46
asc[i] = ((hexCh[2 * i] - 0x41 + 10) << 4);
} else if (hexCh[2 * i] >= 0x61 && hexCh[2 * i] <= 0x66) { //a-f : 0x61-0x66
asc[i] = ((hexCh[2 * i] - 0x61 + 10) << 4);
} else {
return null;
}
if (hexCh[2 * i + 1] >= 0x30 && hexCh[2 * i + 1] <= 0x39) {
asc[i] = (asc[i] | (hexCh[2 * i + 1] - 0x30));
} else if (hexCh[2 * i + 1] >= 0x41 && hexCh[2 * i + 1] <= 0x46) {
asc[i] = (asc[i] | (hexCh[2 * i + 1] - 0x41 + 10));
} else if (hexCh[2 * i + 1] >= 0x61 && hexCh[2 * i + 1] <= 0x66) {
asc[i] = (asc[i] | (hexCh[2 * i + 1] - 0x61 + 10));
} else {
return null;
}
}
return asc;
}
Hex.utf8StrToHex = function(utf8Str) {
var ens = encodeURIComponent(utf8Str);
var es = unescape(ens);
var esLen = es.length;
}
``````markdown
Hex.hexToUtf8Str = function(utf8Str) {
var utf8Byte = Hex.decode(utf8Str);
var latin1Chars = [];
for (var i = 0; i < utf8Byte.length; i++) {
latin1Chars.push(String.fromCharCode(utf8Byte[i]));
}
return decodeURIComponent(escape(latin1Chars.join('')));
}
Hex.bytesToUtf8Str = function(bytesArray) {
var utf8Byte = bytesArray;
var latin1Chars = [];
for (var i = 0; i < utf8Byte.length; i++) {
latin1Chars.push(String.fromCharCode(utf8Byte[i]));
}
return decodeURIComponent(escape(latin1Chars.join('')));
}
Hex.toCharCodeArray = function(chs) {
var chArr = new Array(chs.length);
for (var i = 0; i < chs.length; i++) {
chArr[i] = chs.charCodeAt(i);
}
return chArr;
}
```
``````markdown
## Инструменты для преобразования байтов
### Копирование массива
```javascript
function arrayCopy(src, pos1, dest, pos2, len) {
var realLen = len;
if (pos1 + len > src.length && pos2 + len <= dest.length) {
realLen = src.length - pos1;
} else if (pos2 + len > dest.length && pos1 + len <= src.length) {
realLen = dest.length - pos2;
} else if (pos1 + len <= src.length && pos2 + len <= dest.length) {
realLen = len;
} else if (dest.length < src.length) {
realLen = dest.length - pos2;
} else {
realLen = src.length - pos2;
}
for (var i = 0; i < realLen; i++) {
dest[i + pos2] = src[i + pos1];
}
}
```
### Преобразование длинного целого числа в массив байтов, один длинный целый - 8 байтов
```javascript
function longToByte(num) {
//TODO Здесь в настоящее время преобразуется только нижняя четверть байта, так как в JavaScript нет длинных целых чисел, их нужно обернуть
return new Array(
0,
0,
0,
0,
(num >> 24) & 0x000000FF,
(num >> 16) & 0x000000FF,
(num >> 8) & 0x000000FF,
(num) & 0x000000FF
);
}
/*
/*
Преобразование массива целых чисел в массив байтов, один целое число преобразуется в четыре байта
Возвращает: массив байтов */ function intArrayToByteArray(nums) { var b = new Array(nums.length * 4);
for (var i = 0; i < nums.length; i++) { arrayCopy(intToByte(nums[i]), 0, b, i * 4, 4); } return b; }
/*
/*
*/ function byteArrayToIntArray(b) { var arrLen = Math.ceil(b.length / 4); // округление вверх var out = new Array(arrLen); for (var i = 0; i < b.length; i++) { b[i] = b[i] & 0xFF; // предотвращение влияния отрицательных чисел } for (var i = 0; i < out.length; i++) { out[i] = byteToInt(b, i * 4); } return out; }
export default SM4Util
# Пример использования
```js
// main.js
import './utils/base64.js' // обязательно для импорта, иначе файл не будет корректно собран при сборке приложения
``` // файл с бизнес-логикой.vue
import SM4Util from './utils/SM4.js'
export default {
onShow: function() {
let value = 'hello world! Я juneandgreen.'; // исходный текст
let desKey = 'r18*************'; // ключ 16 байт, 16 байт достаточно, здесь ключ зашифрован
let _SM4Util = new SM4Util(desKey);
// шифрование sm4
let encryptResult = _SM4Util.encryptData_ECB(value);
// расшифрование sm4
let decryptResult = _SM4Util.decryptData_CBC(encryptResult);
console.log('Результат шифрования:', encryptResult) // ByLWO5JW9fw+48XudZnHVf0KdDoSnSxZiUBFVV1ztExJU0zE7qxpk5GgppOGTEXu
console.log('Результат расшифрования:', decryptResult) // hello world! Я juneandgreen.
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )