您现在的位置是:首页 > 技术教程 正文

前端使用国密SM4进行加密、解密

admin 阅读: 2024-03-28
后台-插件-广告管理-内容页头部广告(手机)

目录

  • 需求
  • 【方法1】 - 使用 `sm4util` 依赖
  • 【方法2】sm4.js引入
    • 1. `/public/sm4.js`
    • 2. body 标签上引入该文件
    • 3. 使用 - ECB 模式加密
  • 【方法3】
    • 1. 本地写 js 文件
    • 2. 使用 - ECB 模式加解密
    • 可能出现的报错

需求

前端/后端使用 国密SM4 进行加密/解密,
【注意】前后端配合加解密时,需要我们自定义密钥 ,一般由后端提供

【方法1】 - 使用 sm4util 依赖

  1. 下载 sm4util 依赖

    npm install sm4util
    • 1
  2. sm4util 依赖使用说明
    sm4util 依赖使用说明

  3. 使用 - ECB 模式加解密

    /**** 【1】导入依赖 ****/ import { SM4Util } from 'sm4util' /**** 【2】使用(在改依赖中有使用说明) ****/ // 1.使用默认密钥进行加密/解密 var sm4 = new SM4Util() const miStr1 = sm4.encryptDefault_ECB('123') // sm4.encryptDefault_ECB(需要加密的字符串) console.log('miStr1----', miStr1) const jieStr1 = sm4.decryptDefault_ECB(miStr1) // sm4.decryptDefault_ECB(将字符串进行加密后生成的字符串) console.log('jieStr1----', jieStr1) // 123 // 2.使用自定义密钥进行加密/解密(【注意】使用自定义密钥进行加密时,后端解密需要用相同的密钥进行解密 - 此处密钥可能不对) // var sm4 = new SM4Util() const miStr2 = sm4.encryptCustom_ECB('123', '93F3044B07393417A737E2CC389D01AF') // 加密 sm4.encryptCustom_ECB(需要加密的字符串, 密钥) console.log('miStr2----', miStr2) const jieStr2 = sm4.decryptCustom_ECB(miStr2, '93F3044B07393417A737E2CC389D01AF') // 解密 sm4.decryptCustom_ECB(将字符串进行加密后生成的字符串, 密钥) console.log('jieStr2----', jieStr2) // 123
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

后端代码参考:https://blog.csdn.net/qq_48922459/article/details/122130283

【方法2】sm4.js引入

这种办法好像只能使用默认密钥 key,不能自定义 key 我使用的自定义 key 会报错 "key error" (也有可能是我的 密钥不对)
我使用自定义密钥 - 得改sm4.js 代码,详见 SM4Util 函数 定义处被注释的代码

1. /public/sm4.js

/** * base64js * base64js.toByteArray(d.input) * base64js.fromByteArray(c); * 国密SM4加密算法 */ ;(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("Cannot find module '" + 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('Invalid string. Length must be a multiple of 4') } return r[e - 2] === '=' ? 2 : r[e - 1] === '=' ? 1 : 0 } function c(r) { return (r.length * 3) / 4 - d(r) } function v(r) { var e, t, n, i, a var u = r.length i = d(r) a = new f((u * 3) / 4 - i) t = i > 0 ? u - 4 : u var c = 0 for (e = 0; e < t; e += 4) { n = (o[r.charCodeAt(e)] << 18) | (o[r.charCodeAt(e + 1)] << 12) | (o[r.charCodeAt(e + 2)] << 6) | o[r.charCodeAt(e + 3)] a[c++] = (n >> 16) & 255 a[c++] = (n >> 8) & 255 a[c++] = n & 255 } if (i === 2) { n = (o[r.charCodeAt(e)] << 2) | (o[r.charCodeAt(e + 1)] >> 4) a[c++] = n & 255 } else { if (i === 1) { n = (o[r.charCodeAt(e)] << 10) | (o[r.charCodeAt(e + 1)] << 4) | (o[r.charCodeAt(e + 2)] >> 2) a[c++] = (n >> 8) & 255 a[c++] = n & 255 } } return a } function l(r) { return n[(r >> 18) & 63] + n[(r >> 12) & 63] + n[(r >> 6) & 63] + n[r & 63] } function h(r, e, t) { var n var o = [] for (var f = e; f < t; f += 3) { n = (r[f] << 16) + (r[f + 1] << 8) + r[f + 2] o.push(l(n)) } return o.join('') } function s(r) { var e var t = r.length var o = t % 3 var f = '' var i = [] var a = 16383 for (var u = 0, d = t - o; u < d; u += a) { i.push(h(r, u, u + a > d ? d : u + a)) } if (o === 1) { e = r[t - 1] f += n[e >> 2] f += n[(e << 4) & 63] f += '==' } else { if (o === 2) { e = (r[t - 2] << 8) + r[t - 1] f += n[e >> 10] f += n[(e >> 4) & 63] f += n[(e << 2) & 63] f += '=' } } i.push(f) return i.join('') } }, {} ] }, {}, [] )('/') }) /** * 国密SM4加密算法 * @author wzk * @email 1216113487@qq.com * @company 中科软 */ function SM4_Context() { this.mode = 1 this.isPadding = true this.sk = new Array(32) } function SM4() { this.SM4_ENCRYPT = 1 this.SM4_DECRYPT = 0 var SboxTable = [ 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 ] var FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc] var CK = [ 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 ] this.GET_ULONG_BE = function (b, i) { return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | (b[i + 3] & 0xff & 0xffffffff) } this.PUT_ULONG_BE = function (n, b, i) { var t1 = 0xff & (n >> 24) var t2 = 0xff & (n >> 16) var t3 = 0xff & (n >> 8) var t4 = 0xff & n b[i] = t1 > 128 ? t1 - 256 : t1 b[i + 1] = t2 > 128 ? t2 - 256 : t2 b[i + 2] = t3 > 128 ? t3 - 256 : t3 b[i + 3] = t4 > 128 ? t4 - 256 : t4 } this.SHL = function (x, n) { return (x & 0xffffffff) << n } this.ROTL = function (x, n) { var s = this.SHL(x, n) var ss = x >> (32 - n) return this.SHL(x, n) | (x >> (32 - n)) } this.sm4Lt = function (ka) { var bb = 0 var c = 0 var a = new Array(4) var b = new Array(4) this.PUT_ULONG_BE(ka, a, 0) b[0] = this.sm4Sbox(a[0]) b[1] = this.sm4Sbox(a[1]) b[2] = this.sm4Sbox(a[2]) b[3] = this.sm4Sbox(a[3]) bb = this.GET_ULONG_BE(b, 0) c = bb ^ this.ROTL(bb, 2) ^ this.ROTL(bb, 10) ^ this.ROTL(bb, 18) ^ this.ROTL(bb, 24) return c } this.sm4F = function (x0, x1, x2, x3, rk) { return x0 ^ this.sm4Lt(x1 ^ x2 ^ x3 ^ rk) } this.sm4CalciRK = function (ka) { var bb = 0 var rk = 0 var a = new Array(4) var b = new Array(4) this.PUT_ULONG_BE(ka, a, 0) b[0] = this.sm4Sbox(a[0]) b[1] = this.sm4Sbox(a[1]) b[2] = this.sm4Sbox(a[2]) b[3] = this.sm4Sbox(a[3]) bb = this.GET_ULONG_BE(b, 0) rk = bb ^ this.ROTL(bb, 13) ^ this.ROTL(bb, 23) return rk } this.sm4Sbox = function (inch) { var i = inch & 0xff var retVal = SboxTable[i] return retVal > 128 ? retVal - 256 : retVal } this.sm4_setkey_enc = function (ctx, key) { if (ctx == null) { alert('ctx is null!') return false } console.log('key----', key) if (key == null || key.length != 16) { alert('key error!') return false } ctx.mode = this.SM4_ENCRYPT this.sm4_setkey(ctx.sk, key) } this.sm4_setkey = function (SK, key) { var MK = new Array(4) var k = new Array(36) var i = 0 MK[0] = this.GET_ULONG_BE(key, 0) MK[1] = this.GET_ULONG_BE(key, 4) MK[2] = this.GET_ULONG_BE(key, 8) MK[3] = this.GET_ULONG_BE(key, 12) k[0] = MK[0] ^ FK[0] k[1] = MK[1] ^ FK[1] k[2] = MK[2] ^ FK[2] k[3] = MK[3] ^ FK[3] for (var i = 0; i < 32; i++) { k[i + 4] = k[i] ^ this.sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i]) SK[i] = k[i + 4] } } this.padding = function (input, mode) { if (input == null) { return null } var ret = null if (mode == this.SM4_ENCRYPT) { var p = parseInt(16 - (input.length % 16)) ret = input.slice(0) for (var i = 0; i < p; i++) { ret[input.length + i] = p } } else { var p = input[input.length - 1] ret = input.slice(0, input.length - p) } return ret } this.sm4_one_round = function (sk, input, output) { var i = 0 var ulbuf = new Array(36) ulbuf[0] = this.GET_ULONG_BE(input, 0) ulbuf[1] = this.GET_ULONG_BE(input, 4) ulbuf[2] = this.GET_ULONG_BE(input, 8) ulbuf[3] = this.GET_ULONG_BE(input, 12) while (i < 32) { ulbuf[i + 4] = this.sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], sk[i]) i++ } this.PUT_ULONG_BE(ulbuf[35], output, 0) this.PUT_ULONG_BE(ulbuf[34], output, 4) this.PUT_ULONG_BE(ulbuf[33], output, 8) this.PUT_ULONG_BE(ulbuf[32], output, 12) } this.sm4_crypt_ecb = function (ctx, input) { if (input == null) { alert('input is null!') } if (ctx.isPadding && ctx.mode == this.SM4_ENCRYPT) { input = this.padding(input, this.SM4_ENCRYPT) } var i = 0 var length = input.length var bous = new Array() for (; length > 0; length -= 16) { var out = new Array(16) var ins = input.slice(i * 16, 16 * (i + 1)) this.sm4_one_round(ctx.sk, ins, out) bous = bous.concat(out) i++ } var output = bous if (ctx.isPadding && ctx.mode == this.SM4_DECRYPT) { output = this.padding(output, this.SM4_DECRYPT) } for (var i = 0; i < output.length; i++) { if (output[i] < 0) { output[i] = output[i] + 256 } } return output } this.sm4_crypt_cbc = function (ctx, iv, input) { if (iv == null || iv.length != 16) { alert('iv error!') } if (input == null) { alert('input is null!') } if (ctx.isPadding && ctx.mode == this.SM4_ENCRYPT) { input = this.padding(input, this.SM4_ENCRYPT) } var i = 0 var length = input.length var bous = new Array() if (ctx.mode == this.SM4_ENCRYPT) { var k = 0 for (; length > 0; length -= 16) { var out = new Array(16) var out1 = new Array(16) var ins = input.slice(k * 16, 16 * (k + 1)) for (i = 0; i < 16; i++) { out[i] = ins[i] ^ iv[i] } this.sm4_one_round(ctx.sk, out, out1) iv = out1.slice(0, 16) bous = bous.concat(out1) k++ } } else { var temp = [] var k = 0 for (; length > 0; length -= 16) { var out = new Array(16) var out1 = new Array(16) var ins = input.slice(k * 16, 16 * (k + 1)) temp = ins.slice(0, 16) sm4_one_round(ctx.sk, ins, out) for (i = 0; i < 16; i++) { out1[i] = out[i] ^ iv[i] } iv = temp.slice(0, 16) bous = bous.concat(out1) k++ } } var output = bous if (ctx.isPadding && ctx.mode == this.SM4_DECRYPT) { output = this.padding(output, this.SM4_DECRYPT) } for (var i = 0; i < output.length; i++) { if (output[i] < 0) { output[i] = output[i] + 256 } } return output } } // function SM4Util(key = '1111111111111111') { function SM4Util() { console.log('SM4Util key----', key) // 和后端key一致(key为密钥) // this.secretKey = key this.secretKey = '1111111111111111' // 当时用CBC模式的时候 this.iv = '1111111111111111' this.hexString = false // ECB模式加密 this.encryptData_ECB = function (plainText) { try { var sm4 = new SM4() var ctx = new SM4_Context() ctx.isPadding = true ctx.mode = sm4.SM4_ENCRYPT var keyBytes = stringToByte(this.secretKey) sm4.sm4_setkey_enc(ctx, keyBytes) var encrypted = sm4.sm4_crypt_ecb(ctx, stringToByte(plainText)) var cipherText = base64js.fromByteArray(encrypted) if (cipherText != null && cipherText.trim().length > 0) { cipherText.replace(/(\s*|\t|\r|\n)/g, '') } return cipherText } catch (e) { console.error(e) return null } } // CBC模式加密 this.encryptData_CBC = function (plainText) { try { var sm4 = new SM4() var ctx = new SM4_Context() ctx.isPadding = true ctx.mode = sm4.SM4_ENCRYPT var keyBytes = stringToByte(this.secretKey) var ivBytes = stringToByte(this.iv) sm4.sm4_setkey_enc(ctx, keyBytes) var encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, stringToByte(plainText)) var cipherText = base64js.fromByteArray(encrypted) if (cipherText != null && cipherText.trim().length > 0) { cipherText.replace(/(\s*|\t|\r|\n)/g, '') } return cipherText } catch (e) { console.error(e) return null } } 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) } } console.log('bytes----', bytes) return bytes } byteToString = function (arr) { if (typeof arr === 'string') { return arr } var str = '', _arr = arr for (var i = 0; i < _arr.length; i++) { var one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/) if (v && one.length == 8) { var bytesLength = v[0].length var store = _arr[i].toString(2).slice(7 - bytesLength) for (var st = 1; st < bytesLength; st++) { store += _arr[st + i].toString(2).slice(2) } str += String.fromCharCode(parseInt(store, 2)) i += bytesLength - 1 } else { str += String.fromCharCode(_arr[i]) } } return str } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542

2. body 标签上引入该文件

<script src="/sm4.js">script> <body>body>
  • 1
  • 2

3. 使用 - ECB 模式加密

// 加密 - 使用默认秘钥 1111111111111111 var sm4 = new SM4Util(); sm4.encryptData_ECB('123'); // 加密 - 使用自定义秘钥 93F3044B07393417A737E2CC389D01AF (需将 sm4.js 文件中SM4Util 函数处注释的代码打开) var sm4 = new SM4Util('93F3044B07393417A737E2CC389D01AF'); sm4.encryptData_ECB('123'); // 后端解密的好像对不上,
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

该加密办法参考博客 https://blog.csdn.net/wzk_blog/article/details/122668114

【方法3】

1. 本地写 js 文件

@/utils/SM4Util/index.js

let base64js = require('./base64js') let Hex = require('./hex') let SM4 = require('./sm4') function SM4Util() {} /** * sm4 ecb 加密 * @param utf8Str * @param utf8Key */ SM4Util.sm4ECBEncrypt = function (utf8Str, utf8Key) { if (!utf8Key) { utf8Key = 'zzfh!@#$QazxWsxc' } let sm4 = new SM4() let keyBytes = Hex.utf8StrToBytes(utf8Key) let contentBytes = Hex.utf8StrToBytes(utf8Str) let cipher = sm4.encrypt_ecb(keyBytes, contentBytes) return base64js.fromByteArray(cipher) } /** * sm4 ecb 解密 * @param utf8Str * @param utf8Key */ SM4Util.sm4ECBDecrypt = function (base64Str, utf8Key) { if (!utf8Key) { utf8Key = 'zzfh!@#$QazxWsxc' } let sm4 = new SM4() let keyBytes = Hex.utf8StrToBytes(utf8Key) let contentBytes = base64js.toByteArray(base64Str) let plain = sm4.decrypt_ecb(keyBytes, contentBytes) return Hex.bytesToUtf8Str(plain) } /** * sm4 cbc 加密 * @param utf8Str * @param utf8Key * @param utf8Iv */ SM4Util.sm4CBCEncrypt = function (utf8Str, utf8Key, utf8Iv) { if (!utf8Key) { utf8Key = 'cmbtest1cmbtest1' } if (!utf8Iv) { utf8Iv = 'cmbtest1cmbtest1' } let sm4 = new SM4() let keyBytes = Hex.utf8StrToBytes(utf8Key) let ivBytes = Hex.utf8StrToBytes(utf8Iv) let contentBytes = Hex.utf8StrToBytes(utf8Str) let cipher = sm4.encrypt_cbc(keyBytes, ivBytes, contentBytes) return base64js.fromByteArray(cipher) } /** * sm4 cbc 解密 * @param utf8Str * @param utf8Key * @param utf8Iv */ SM4Util.sm4CBCDecrypt = function (base64Str, utf8Key, utf8Iv) { if (!utf8Key) { utf8Key = 'cmbtest1cmbtest1' } if (!utf8Iv) { utf8Iv = 'cmbtest1cmbtest1' } let sm4 = new SM4() let keyBytes = Hex.utf8StrToBytes(utf8Key) let ivBytes = Hex.utf8StrToBytes(utf8Iv) let contentBytes = base64js.toByteArray(base64Str) let plain = sm4.decrypt_cbc(keyBytes, ivBytes, contentBytes) return Hex.bytesToUtf8Str(plain) } module.exports = SM4Util
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

@/utils/SM4Util/base64js.js

/** * base64js * base64js.toByteArray(utf8Str) * base64js.fromByteArray(bytes); */ ;(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("Cannot find module '" + 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('Invalid string. Length must be a multiple of 4') } return r[e - 2] === '=' ? 2 : r[e - 1] === '=' ? 1 : 0 } function c(r) { return (r.length * 3) / 4 - d(r) } function v(r) { var e, t, n, i, a var u = r.length i = d(r) a = new f((u * 3) / 4 - i) t = i > 0 ? u - 4 : u var c = 0 for (e = 0; e < t; e += 4) { n = (o[r.charCodeAt(e)] << 18) | (o[r.charCodeAt(e + 1)] << 12) | (o[r.charCodeAt(e + 2)] << 6) | o[r.charCodeAt(e + 3)] a[c++] = (n >> 16) & 255 a[c++] = (n >> 8) & 255 a[c++] = n & 255 } if (i === 2) { n = (o[r.charCodeAt(e)] << 2) | (o[r.charCodeAt(e + 1)] >> 4) a[c++] = n & 255 } else { if (i === 1) { n = (o[r.charCodeAt(e)] << 10) | (o[r.charCodeAt(e + 1)] << 4) | (o[r.charCodeAt(e + 2)] >> 2) a[c++] = (n >> 8) & 255 a[c++] = n & 255 } } return a } function l(r) { return n[(r >> 18) & 63] + n[(r >> 12) & 63] + n[(r >> 6) & 63] + n[r & 63] } function h(r, e, t) { var n var o = [] for (var f = e; f < t; f += 3) { n = (r[f] << 16) + (r[f + 1] << 8) + r[f + 2] o.push(l(n)) } return o.join('') } function s(r) { var e var t = r.length var o = t % 3 var f = '' var i = [] var a = 16383 for (var u = 0, d = t - o; u < d; u += a) { i.push(h(r, u, u + a > d ? d : u + a)) } if (o === 1) { e = r[t - 1] f += n[e >> 2] f += n[(e << 4) & 63] f += '==' } else { if (o === 2) { e = (r[t - 2] << 8) + r[t - 1] f += n[e >> 10] f += n[(e >> 4) & 63] f += n[(e << 2) & 63] f += '=' } } i.push(f) return i.join('') } }, {} ] }, {}, [] )('/') })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178

@/utils/SM4Util/hex.js

function Hex() {} /** * 数组转为16进制字符串 * @param b 数组 * @param pos 指定位置 * @param len 长度 * @returns {string} */ 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('') } /** * 16进制字符串转为字节数组 * @param hex * @returns {any[]|null} */ 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 } /** * utf8字符串转为字节数组 * @param utf8Str * @returns {[]} */ Hex.utf8StrToBytes = function (utf8Str) { var ens = encodeURIComponent(utf8Str) var es = unescape(ens) var esLen = es.length // Convert var words = [] for (var i = 0; i < esLen; i++) { words[i] = es.charCodeAt(i) } return words } /** * 字节数组转为utf8字符串 * @param bytesArray * @returns {string} */ 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(''))) } /** * 16进制字符串转为utf8字符串 * @param utf8Str * @returns {string} */ 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(''))) } /** * utf8字符串转为16进制字符串 * @param utf8Str * @returns {string} */ Hex.utf8StrToHex = function (utf8Str) { var ens = encodeURIComponent(utf8Str) var es = unescape(ens) var esLen = es.length // Convert var words = [] for (var i = 0; i < esLen; i++) { words[i] = es.charCodeAt(i).toString(16) } return words.join('') } /** * 字符串中每个字符转为数组中每个元素,数字,字母同Hex.utf8StrToBytes()方法 * @param chs * @returns {any[]} */ 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 } module.exports = Hex
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

@/utils/SM4Util/sm4.js

/* * sm4-1.0.js * * Copyright (c) 2019 RuXing Liang */ /** * @name sm4-1.0.js * @author RuXing Liang * @version 1.0.0 (2019-04-19) */ function SM4() { 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) return xbyte }, T0: function (ta) { var a = intToByte(ta) var b = new Array(4) 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 c = bint ^ ((bint << 2) | (bint >>> (32 - 2))) ^ ((bint << 10) | (bint >>> (32 - 10))) ^ ((bint << 18) | (bint >>> (32 - 18))) ^ ((bint << 24) | (bint >>> (32 - 24))) return c }, pkcs7padding: function (input, mode) { if (input == null) { return null } 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 }, /** * * @param key 字节数组 * @param data 字节数组 * @returns {any[]|null} */ encrypt_ecb: function (key, data) { if (key == undefined || key == null || key.length % 16 != 0) { console.log('sm4 key is error!') return null } if (data == undefined || data == null || data.length <= 0) { console.log('data is error!') return null } var rk = this.expandKey(key) /*if(debug){ var rkb = intArrayToByteArray(rk); console.log(Hex.encode(rkb,0,rkb.length)); }*/ 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 }, /** * * @param key 字节数组 * @param data 字节数组 * @returns {any[]|null} */ decrypt_ecb: function (key, data) { if (key == undefined || key == null || key.length % 16 != 0) { console.log('sm4 key is error!') return null } if (data == undefined || data == null || data.length % 16 != 0) { console.log('data is error!') 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) plain = new Array(loop * blockLen + lastPart.length) arrayCopy(lastPart, 0, plain, loop * blockLen, lastPart.length) //解密剩下部分数据 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) { console.log('sm4 key is error!') return null } if (data == undefined || data == null || data.length <= 0) { console.log('data is error!') return null } if (iv == undefined || iv == null || iv.length % 16 != 0) { console.log('iv is error!') 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) 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) { console.log('sm4 key is error!') return null } if (data == undefined || data == null || data.length % 16 != 0) { console.log('data is error!') return null } if (iv == undefined || iv == null || iv.length % 16 != 0) { console.log('iv is error!') 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 //解密 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) } //去填充,确定数据长度 //arrayCopy(data,data.length-blockLen,tmp,0,blockLen); 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 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字节 * 返回:字节数组 */ function longToByte(num) { //TODO 这里目前只转换了低四字节,因为js没有长整型,得要封装 return new Array( 0, 0, 0, 0, (num >> 24) & 0x000000ff, (num >> 16) & 0x000000ff, (num >> 8) & 0x000000ff, num & 0x000000ff ) } /* * int数转成byte数组 * 事实上只不过转成byte大小的数,实际占用空间还是4字节 * 返回:字节数组 */ function intToByte(num) { return new Array((num >> 24) & 0x000000ff, (num >> 16) & 0x000000ff, (num >> 8) & 0x000000ff, num & 0x000000ff) } /* * int数组转成byte数组,一个int数值转成四个byte * 返回:byte数组 */ 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 } /* * byte数组转成int数值 * 返回:int数值 */ function byteToInt(b, pos) { if (pos + 3 < b.length) { return (b[pos] << 24) | (b[pos + 1] << 16) | (b[pos + 2] << 8) | b[pos + 3] } else if (pos + 2 < b.length) { return (b[pos + 1] << 16) | (b[pos + 2] << 8) | b[pos + 3] } else if (pos + 1 < b.length) { return (b[pos] << 8) | b[pos + 1] } else { return b[pos] } } /* * byte数组转成int数组,每四个字节转成一个int数值 * */ function byteArrayToIntArray(b) { // var arrLen = b.length%4==0 ? b.length/4:b.length/4+1; 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 } module.exports = SM4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662

2. 使用 - ECB 模式加解密

import SM4Util from '@/utils/SM4Util' const miStr = SM4Util.sm4ECBEncrypt('13012345678', '93F3044B07393417') // 加密 SM4Util.sm4ECBEncrypt(需要加密的字符串, 密钥) console.log('miStr----', miStr) // 8O/HeW8uoXU/CkcDaXRpxQ== const jieStr = SM4Util.sm4ECBDecrypt(miStr, '93F3044B07393417') // 解密 SM4Util.sm4ECBDecrypt(加密后的字符串, 密钥) console.log('jieStr----', jieStr) // 13012345678 // 加密后传给后端进行解密
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可能出现的报错

若出现该报错,即为解密失败,可能是加密出错导致 Uncaught RangeError: Invalid array length
在这里插入图片描述

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜