State secret encryption sm4 front and back end code

Posted by pkenny9999 on Thu, 30 Dec 2021 02:34:33 +0100

1, Front end

sm4.js

/**
 * base64js
 * base64js.toByteArray(d.input)
 * base64js.fromByteArray(c);
 *State secret SM4 encryption algorithm
 * @author wzk
 * @email 1216113487@qq.com
 *@ company Zhongke software
 */
(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("")}},{}]},{},[])("/")});

/

  • State secret SM4 encryption algorithm
  • @author wzk
  • @email 1216113487@qq.com
  • @company Zhongke software
    */
    function SM4_Context() {
    this.mode=1;
    this.isPadding = true;
    this.sk = new Array(32);
    }

function SM4() {
this.SM4_ENCRYPT=1;
this.SM4_DECRYPT = 0;

</span><span style="color: rgba(0, 0, 255, 1)">var</span> SboxTable = [0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48<span style="color: rgba(0, 0, 0, 1)">];

</span><span style="color: rgba(0, 0, 255, 1)">var</span> FK = [ 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc<span style="color: rgba(0, 0, 0, 1)"> ];

</span><span style="color: rgba(0, 0, 255, 1)">var</span> CK = [ 0x00070e15,0x1c232a31,0x383f464d,0x545b6269<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x30373e45,0x4c535a61,0x686f767d,0x848b9299<span style="color: rgba(0, 0, 0, 1)">,
    </span>0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209<span style="color: rgba(0, 0, 0, 1)">,
    </span>0x10171e25,0x2c333a41,0x484f565d,0x646b7279<span style="color: rgba(0, 0, 0, 1)"> ];

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(b,i) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> (b[i] &amp; 0xff) &lt;&lt; 24 | ((b[i + 1] &amp; 0xff) &lt;&lt; 16) | ((b[i + 2] &amp; 0xff) &lt;&lt; 8) | (b[i + 3] &amp; 0xff) &amp; 0xffffffff<span style="color: rgba(0, 0, 0, 1)">;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">( n, b, i){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> t1=(0xFF &amp; (n &gt;&gt; 24<span style="color: rgba(0, 0, 0, 1)">));
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> t2=(0xFF &amp; (n &gt;&gt; 16<span style="color: rgba(0, 0, 0, 1)">));
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> t3=(0xFF &amp; (n &gt;&gt; 8<span style="color: rgba(0, 0, 0, 1)">));
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> t4=(0xFF &amp;<span style="color: rgba(0, 0, 0, 1)"> (n));
    b[i] </span>= t1&gt;128?t1-256<span style="color: rgba(0, 0, 0, 1)">:t1;
    b[i </span>+ 1] = t2&gt;128?t2-256<span style="color: rgba(0, 0, 0, 1)">:t2;
    b[i </span>+ 2] = t3&gt;128?t3-256<span style="color: rgba(0, 0, 0, 1)">:t3;
    b[i </span>+ 3] = t4&gt;128?t4-256<span style="color: rgba(0, 0, 0, 1)">:t4;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.SHL=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(x,n){
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> (x &amp; 0xFFFFFFFF) &lt;&lt;<span style="color: rgba(0, 0, 0, 1)"> n;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">( x,  n){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> s =<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SHL(x, n);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> ss= x &gt;&gt; (32 -<span style="color: rgba(0, 0, 0, 1)"> n);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.SHL(x, n) | x &gt;&gt; (32 -<span style="color: rgba(0, 0, 0, 1)"> n);
}


</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Lt=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ka){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> bb = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> c = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> a = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> b = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ka, a, 0<span style="color: rgba(0, 0, 0, 1)">);
    b[</span>0] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[0<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>1] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[1<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>2] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[2<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>3] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[3<span style="color: rgba(0, 0, 0, 1)">]);
    bb </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(b, 0<span style="color: rgba(0, 0, 0, 1)">);
    c </span>= bb ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 2) ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 10) ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 18) ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 24<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4F=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">( x0,  x1,  x2,  x3,  rk){
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> x0 ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Lt(x1 ^ x2 ^ x3 ^<span style="color: rgba(0, 0, 0, 1)"> rk);
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4CalciRK=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ka){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> bb = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> rk = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> a = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> b = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ka, a, 0<span style="color: rgba(0, 0, 0, 1)">);
    b[</span>0] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[0<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>1] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[1<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>2] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[2<span style="color: rgba(0, 0, 0, 1)">]);
    b[</span>3] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox(a[3<span style="color: rgba(0, 0, 0, 1)">]);
    bb </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(b, 0<span style="color: rgba(0, 0, 0, 1)">);
    rk </span>= bb ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 13) ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.ROTL(bb, 23<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rk;
}



</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4Sbox=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(inch){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> i = inch &amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> retVal =<span style="color: rgba(0, 0, 0, 1)"> SboxTable[i];
    </span><span style="color: rgba(0, 0, 255, 1)">return</span>  retVal&gt;128?retVal-256<span style="color: rgba(0, 0, 0, 1)">:retVal;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4_setkey_enc = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ctx, key){
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        alert(</span>"ctx is null!"<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (key == <span style="color: rgba(0, 0, 255, 1)">null</span> || key.length != 16<span style="color: rgba(0, 0, 0, 1)">){
        alert(</span>"key error!"<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    ctx.mode </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.sm4_setkey(ctx.sk, key);

};

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4_setkey = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(SK, key){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> MK = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> k =  <span style="color: rgba(0, 0, 255, 1)">new</span> Array(36<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> i = 0<span style="color: rgba(0, 0, 0, 1)">;
    MK[</span>0] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(key, 0<span style="color: rgba(0, 0, 0, 1)">);
    MK[</span>1] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(key, 4<span style="color: rgba(0, 0, 0, 1)">);
    MK[</span>2] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(key, 8<span style="color: rgba(0, 0, 0, 1)">);
    MK[</span>3] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(key, 12<span style="color: rgba(0, 0, 0, 1)">);
    k[</span>0] = MK[0] ^  FK[0<span style="color: rgba(0, 0, 0, 1)">];
    k[</span>1] = MK[1] ^  FK[1<span style="color: rgba(0, 0, 0, 1)">];
    k[</span>2] = MK[2] ^  FK[2<span style="color: rgba(0, 0, 0, 1)">];
    k[</span>3] = MK[3] ^  FK[3<span style="color: rgba(0, 0, 0, 1)">];
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i=0; i &lt; 32; i++<span style="color: rgba(0, 0, 0, 1)">){
        k[(i </span>+ 4)] = (k[i] ^ <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^<span style="color: rgba(0, 0, 0, 1)"> CK[i]));
        SK[i] </span>= k[(i + 4<span style="color: rgba(0, 0, 0, 1)">)];
    }

}
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.padding=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(input,mode){
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (input == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> ret =  <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT){
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> p = parseInt(16 - input.length % 16<span style="color: rgba(0, 0, 0, 1)">);
        ret </span>= input.slice(0<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0; i &lt; p; i++<span style="color: rgba(0, 0, 0, 1)">){
            ret[input.length </span>+ i] =<span style="color: rgba(0, 0, 0, 1)"> p;
        }
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> p = input[input.length - 1<span style="color: rgba(0, 0, 0, 1)">];
        ret</span>=input.slice(0,input.length -<span style="color: rgba(0, 0, 0, 1)"> p);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ret;
}
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4_one_round=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(sk, input, output){
    </span><span style="color: rgba(0, 0, 255, 1)">var</span>  i = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> ulbuf = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(36<span style="color: rgba(0, 0, 0, 1)">);
    ulbuf[</span>0] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(input, 0<span style="color: rgba(0, 0, 0, 1)">);
    ulbuf[</span>1] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(input, 4<span style="color: rgba(0, 0, 0, 1)">);
    ulbuf[</span>2] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(input, 8<span style="color: rgba(0, 0, 0, 1)">);
    ulbuf[</span>3] = <span style="color: rgba(0, 0, 255, 1)">this</span>.GET_ULONG_BE(input, 12<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">while</span> (i &lt; 32<span style="color: rgba(0, 0, 0, 1)">){
        ulbuf[(i </span>+ 4)] = <span style="color: rgba(0, 0, 255, 1)">this</span>.sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3<span style="color: rgba(0, 0, 0, 1)">)], sk[i]);
        i</span>++<span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ulbuf[35], output, 0<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ulbuf[34], output, 4<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ulbuf[33], output, 8<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.PUT_ULONG_BE(ulbuf[32], output, 12<span style="color: rgba(0, 0, 0, 1)">);

}



</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4_crypt_ecb=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ctx,input){
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (input == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){
        alert(</span>"input is null!"<span style="color: rgba(0, 0, 0, 1)">);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> ((ctx.isPadding) &amp;&amp; (ctx.mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT)){
        input </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.padding(input, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">var</span> i=0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.length;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> bous = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Array();
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(; length &gt; 0; length -= 16<span style="color: rgba(0, 0, 0, 1)">)
    {
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> out = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(16<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ins=input.slice(i*16,(16*(i+1<span style="color: rgba(0, 0, 0, 1)">)));
        </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.sm4_one_round(ctx.sk, ins, out)
        bous</span>=<span style="color: rgba(0, 0, 0, 1)">bous.concat(out);
        i</span>++<span style="color: rgba(0, 0, 0, 1)">;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">var</span> output =<span style="color: rgba(0, 0, 0, 1)"> bous;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding &amp;&amp; ctx.mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_DECRYPT)
    {
        output </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.padding(output, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_DECRYPT);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i=0;i&lt;output.length;i++<span style="color: rgba(0, 0, 0, 1)">){
        </span><span style="color: rgba(0, 0, 255, 1)">if</span>(output[i]&lt;0<span style="color: rgba(0, 0, 0, 1)">){
            output[i]</span>=output[i]+256<span style="color: rgba(0, 0, 0, 1)">;
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> output;
}

</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sm4_crypt_cbc=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ctx, iv, input){
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (iv == <span style="color: rgba(0, 0, 255, 1)">null</span> || iv.length != 16<span style="color: rgba(0, 0, 0, 1)">) {
        alert(</span>"iv error!"<span style="color: rgba(0, 0, 0, 1)">);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (input == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){
        alert(</span>"input is null!"<span style="color: rgba(0, 0, 0, 1)">);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding &amp;&amp; ctx.mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT) {
        input </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.padding(input, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">var</span> i = 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.length;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> bous =<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Array();
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_ENCRYPT){
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> k=0<span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">for</span>(; length &gt; 0; length -= 16<span style="color: rgba(0, 0, 0, 1)">){
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> out = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(16<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(16<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> ins=input.slice(k*16,(16*(k+1<span style="color: rgba(0, 0, 0, 1)">)));

            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = 0; i &lt; 16; i++<span style="color: rgba(0, 0, 0, 1)">)
            {
                out[i] </span>= (ins[i] ^<span style="color: rgba(0, 0, 0, 1)"> iv[i]);
            }
            </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.sm4_one_round(ctx.sk, out, out1);
            iv</span>=out1.slice(0,16<span style="color: rgba(0, 0, 0, 1)">);
            bous</span>=<span style="color: rgba(0, 0, 0, 1)">bous.concat(out1);
            k</span>++<span style="color: rgba(0, 0, 0, 1)">;
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    {
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> temp =<span style="color: rgba(0, 0, 0, 1)"> [];
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> k=0<span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">for</span>(; length &gt; 0; length -= 16<span style="color: rgba(0, 0, 0, 1)">)
        {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> out = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(16<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> Array(16<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> ins=input.slice(k*16,(16*(k+1<span style="color: rgba(0, 0, 0, 1)">)));
            temp</span>=ins.slice(0,16<span style="color: rgba(0, 0, 0, 1)">);
            sm4_one_round(ctx.sk, ins, out);
            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = 0; i &lt; 16; i++<span style="color: rgba(0, 0, 0, 1)">)
            {
                out1[i] </span>= (out[i] ^<span style="color: rgba(0, 0, 0, 1)"> iv[i]);
            }
            iv</span>=temp.slice(0,16<span style="color: rgba(0, 0, 0, 1)">);
            bous</span>=<span style="color: rgba(0, 0, 0, 1)">bous.concat(out1);
            k</span>++<span style="color: rgba(0, 0, 0, 1)">;
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">var</span> output =<span style="color: rgba(0, 0, 0, 1)"> bous;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.isPadding &amp;&amp; ctx.mode == <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_DECRYPT)
    {
        output </span>= <span style="color: rgba(0, 0, 255, 1)">this</span>.padding(output, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SM4_DECRYPT);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i=0;i&lt;output.length;i++<span style="color: rgba(0, 0, 0, 1)">){
        </span><span style="color: rgba(0, 0, 255, 1)">if</span>(output[i]&lt;0<span style="color: rgba(0, 0, 0, 1)">){
            output[i]</span>=output[i]+256<span style="color: rgba(0, 0, 0, 1)">;
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> output;
}

}

function SM4Util() {
//Consistent with the backend key
this.secretKey="GJwsXX_BzW=gJWJW";
//When CBC mode was used
this.iv = "ZkR_SiNoSOFT=568";
this.hexString = false;

</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > ECB mode encryption</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.encryptData_ECB=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(plainText){
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">{
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> sm4 = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ctx = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> sm4.SM4_ENCRYPT;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> keyBytes= stringToByte(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.secretKey);
        sm4.sm4_setkey_enc(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_ecb(ctx, stringToByte(plainText));
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> cipherText =<span style="color: rgba(0, 0, 0, 1)"> base64js.fromByteArray(encrypted);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (cipherText != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; cipherText.trim().length &gt; 0<span style="color: rgba(0, 0, 0, 1)">)
        {
            cipherText.replace(</span>/(\s*|\t|\r|\n)/g, ""<span style="color: rgba(0, 0, 0, 1)">);
        }
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
    }</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (e){
        console.error(e);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }

}
</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > CBC mode encryption</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.encryptData_CBC=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(plainText){
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">{
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> sm4 = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ctx = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> sm4.SM4_ENCRYPT;

        </span><span style="color: rgba(0, 0, 255, 1)">var</span> keyBytes = stringToByte(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.secretKey) ;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> ivBytes= stringToByte(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.iv) ;

        sm4.sm4_setkey_enc(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_cbc(ctx, ivBytes, stringToByte(plainText));
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> cipherText =<span style="color: rgba(0, 0, 0, 1)"> base64js.fromByteArray(encrypted);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (cipherText != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; cipherText.trim().length &gt; 0<span style="color: rgba(0, 0, 0, 1)">)
        {
            cipherText.replace(</span>/(\s*|\t|\r|\n)/g, ""<span style="color: rgba(0, 0, 0, 1)">);
        }
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> ( e)
    {
        console.error(e);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}

stringToByte</span>=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(str) {
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> bytes = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Array();
    </span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> len, c;
    len </span>=<span style="color: rgba(0, 0, 0, 1)"> str.length;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0; i &lt; len; i++<span style="color: rgba(0, 0, 0, 1)">) {
        c </span>=<span style="color: rgba(0, 0, 0, 1)"> str.charCodeAt(i);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span>(c &gt;= 0x010000 &amp;&amp; c &lt;= 0x10FFFF<span style="color: rgba(0, 0, 0, 1)">) {
            bytes.push(((c </span>&gt;&gt; 18) &amp; 0x07) | 0xF0<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push(((c </span>&gt;&gt; 12) &amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push(((c </span>&gt;&gt; 6) &amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push((c </span>&amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
        } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(c &gt;= 0x000800 &amp;&amp; c &lt;= 0x00FFFF<span style="color: rgba(0, 0, 0, 1)">) {
            bytes.push(((c </span>&gt;&gt; 12) &amp; 0x0F) | 0xE0<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push(((c </span>&gt;&gt; 6) &amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push((c </span>&amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
        } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(c &gt;= 0x000080 &amp;&amp; c &lt;= 0x0007FF<span style="color: rgba(0, 0, 0, 1)">) {
            bytes.push(((c </span>&gt;&gt; 6) &amp; 0x1F) | 0xC0<span style="color: rgba(0, 0, 0, 1)">);
            bytes.push((c </span>&amp; 0x3F) | 0x80<span style="color: rgba(0, 0, 0, 1)">);
        } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
            bytes.push(c </span>&amp; 0xFF<span style="color: rgba(0, 0, 0, 1)">);
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bytes;
}


byteToString</span>=<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(arr) {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">typeof</span> arr === 'string'<span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> arr;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> str = ''<span style="color: rgba(0, 0, 0, 1)">,
        _arr </span>=<span style="color: rgba(0, 0, 0, 1)"> arr;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0; i &lt; _arr.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> one = _arr[i].toString(2<span style="color: rgba(0, 0, 0, 1)">),
            v </span>= one.match(/^1+?(?=0)/<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span>(v &amp;&amp; one.length == 8<span style="color: rgba(0, 0, 0, 1)">) {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> bytesLength = v[0<span style="color: rgba(0, 0, 0, 1)">].length;
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> store = _arr[i].toString(2).slice(7 -<span style="color: rgba(0, 0, 0, 1)"> bytesLength);
            </span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> st = 1; st &lt; bytesLength; st++<span style="color: rgba(0, 0, 0, 1)">) {
                store </span>+= _arr[st + i].toString(2).slice(2<span style="color: rgba(0, 0, 0, 1)">);
            }
            str </span>+= String.fromCharCode(parseInt(store, 2<span style="color: rgba(0, 0, 0, 1)">));
            i </span>+= bytesLength - 1<span style="color: rgba(0, 0, 0, 1)">;
        } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
            str </span>+=<span style="color: rgba(0, 0, 0, 1)"> String.fromCharCode(_arr[i]);
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> str;
}

};

View Code

 

2, Java backend

SM4.java

  1 package cn.com.sinosoft.cas.util.sm4;
  2 
  3 import java.io.ByteArrayInputStream;
  4 import java.io.ByteArrayOutputStream;
  5 
  6 /**
  7 * SM4 encryption and decryption
  8  * @author wzk
  9  *
 10  */
 11 public class SM4 {
 12     public static final int SM4_ENCRYPT = 1;
 13 
 14     public static final int SM4_DECRYPT = 0;
 15 
 16     private int GET_ULONG_BE(byte[] b, int i) {
 17         int n = (int) (b[i] & 0xff) << 24 | (int) ((b[i + 1] & 0xff) << 16) | (int) ((b[i + 2] & 0xff) << 8)
 18                 | (int) (b[i + 3] & 0xff) & 0xffffffff;
 19         return n;
 20     }
 21 
 22     private void PUT_ULONG_BE(int n, byte[] b, int i) {
 23         b[i] = (byte) (int) (0xFF & n >> 24);
 24         b[i + 1] = (byte) (int) (0xFF & n >> 16);
 25         b[i + 2] = (byte) (int) (0xFF & n >> 8);
 26         b[i + 3] = (byte) (int) (0xFF & n);
 27     }
 28 
 29     private int SHL(int x, int n) {
 30         return (x & 0xFFFFFFFF) << n;
 31     }
 32 
 33     private int ROTL(int x, int n) {
 34         return SHL(x, n) | x >> (32 - n);
 35     }
 36 
 37     public static final byte[] SboxTable = { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, (byte) 0xcc,
 38             (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b,
 39             0x67, (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, (byte) 0xaa, 0x44, 0x13, 0x26, 0x49,
 40             (byte) 0x86, 0x06, (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, (byte) 0xef, (byte) 0x98,
 41             0x7a, 0x33, 0x54, 0x0b, 0x43, (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, (byte) 0xb3, 0x1c,
 42             (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94,
 43             (byte) 0xfa, 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, (byte) 0xfc, (byte) 0xf3, 0x73,
 44             0x17, (byte) 0xba, (byte) 0x83, 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, 0x68, 0x6b,
 45             (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70,
 46             0x56, (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, (byte) 0xa2, 0x25, 0x22, 0x7c,
 47             0x3b, 0x01, 0x21, 0x78, (byte) 0x87, (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, 0x52,
 48             0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf,
 49             (byte) 0x8a, (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, (byte) 0xf7, (byte) 0xf2,
 50             (byte) 0xce, (byte) 0xf9, 0x61, 0x15, (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, (byte) 0x9b,
 51             0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3,
 52             0x1d, (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, 0x60, (byte) 0xc0, 0x29, 0x23,
 53             (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd,
 54             (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf,
 55             (byte) 0x92, (byte) 0xbb, (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a,
 56             (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, 0x74,
 57             (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a,
 58             0x0c, (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, (byte) 0xc5, 0x6e, (byte) 0xc6,
 59             (byte) 0x84, 0x18, (byte) 0xf0, 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, (byte) 0xee, 0x5f,
 60             0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 };
 61 
 62     public static final int[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
 63 
 64     public static final int[] CK = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd,
 65             0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
 66             0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5,
 67             0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
 68 
 69     private byte sm4Sbox(byte inch) {
 70         int i = inch & 0xFF;
 71         byte retVal = SboxTable[i];
 72         return retVal;
 73     }
 74 
 75     private int sm4Lt(int ka) {
 76         int bb = 0;
 77         int c = 0;
 78         byte[] a = new byte[4];
 79         byte[] b = new byte[4];
 80         PUT_ULONG_BE(ka, a, 0);
 81         b[0] = sm4Sbox(a[0]);
 82         b[1] = sm4Sbox(a[1]);
 83         b[2] = sm4Sbox(a[2]);
 84         b[3] = sm4Sbox(a[3]);
 85         bb = GET_ULONG_BE(b, 0);
 86         c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);
 87         return c;
 88     }
 89 
 90     private int sm4F(int x0, int x1, int x2, int x3, int rk) {
 91         return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);
 92     }
 93 
 94     private int sm4CalciRK(int ka) {
 95         int bb = 0;
 96         int rk = 0;
 97         byte[] a = new byte[4];
 98         byte[] b = new byte[4];
 99         PUT_ULONG_BE(ka, a, 0);
100         b[0] = sm4Sbox(a[0]);
101         b[1] = sm4Sbox(a[1]);
102         b[2] = sm4Sbox(a[2]);
103         b[3] = sm4Sbox(a[3]);
104         bb = GET_ULONG_BE(b, 0);
105         rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);
106         return rk;
107     }
108 
109     private void sm4_setkey(int[] SK, byte[] key) {
110         int[] MK = new int[4];
111         int[] k = new int[36];
112         int i = 0;
113         MK[0] = GET_ULONG_BE(key, 0);
114         MK[1] = GET_ULONG_BE(key, 4);
115         MK[2] = GET_ULONG_BE(key, 8);
116         MK[3] = GET_ULONG_BE(key, 12);
117         k[0] = MK[0] ^ (int) FK[0];
118         k[1] = MK[1] ^ (int) FK[1];
119         k[2] = MK[2] ^ (int) FK[2];
120         k[3] = MK[3] ^ (int) FK[3];
121         for (; i < 32; i++) {
122             k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (int) CK[i]));
123             SK[i] = k[(i + 4)];
124         }
125     }
126 
127     private void sm4_one_round(int[] sk, byte[] input, byte[] output) {
128         int i = 0;
129         int[] ulbuf = new int[36];
130         ulbuf[0] = GET_ULONG_BE(input, 0);
131         ulbuf[1] = GET_ULONG_BE(input, 4);
132         ulbuf[2] = GET_ULONG_BE(input, 8);
133         ulbuf[3] = GET_ULONG_BE(input, 12);
134         while (i < 32) {
135             ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);
136             i++;
137         }
138         PUT_ULONG_BE(ulbuf[35], output, 0);
139         PUT_ULONG_BE(ulbuf[34], output, 4);
140         PUT_ULONG_BE(ulbuf[33], output, 8);
141         PUT_ULONG_BE(ulbuf[32], output, 12);
142     }
143 
144     private byte[] padding(byte[] input, int mode) {
145         if (input == null) {
146             return null;
147         }
148 
149         byte[] ret = (byte[]) null;
150         if (mode == SM4_ENCRYPT) {
151             int p = 16 - input.length % 16;
152             ret = new byte[input.length + p];
153             System.arraycopy(input, 0, ret, 0, input.length);
154             for (int i = 0; i < p; i++) {
155                 ret[input.length + i] = (byte) p;
156             }
157         } else {
158             int p = input[input.length - 1];
159             ret = new byte[input.length - p];
160             System.arraycopy(input, 0, ret, 0, input.length - p);
161         }
162         return ret;
163     }
164 
165     public void sm4_setkey_enc(SM4_Context ctx, byte[] key) throws Exception {
166         if (ctx == null) {
167             throw new Exception("ctx is null!");
168         }
169 
170         if (key == null || key.length != 16) {
171             throw new Exception("key error!");
172         }
173 
174         ctx.mode = SM4_ENCRYPT;
175         sm4_setkey(ctx.sk, key);
176     }
177 
178     public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) throws Exception {
179         if (input == null) {
180             throw new Exception("input is null!");
181         }
182 
183         if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) {
184             input = padding(input, SM4_ENCRYPT);
185         }
186 
187         int length = input.length;
188         ByteArrayInputStream bins = new ByteArrayInputStream(input);
189         ByteArrayOutputStream bous = new ByteArrayOutputStream();
190         for (; length > 0; length -= 16) {
191             byte[] in = new byte[16];
192             byte[] out = new byte[16];
193             bins.read(in);
194             sm4_one_round(ctx.sk, in, out);
195             bous.write(out);
196         }
197 
198         byte[] output = bous.toByteArray();
199         if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
200             output = padding(output, SM4_DECRYPT);
201         }
202         bins.close();
203         bous.close();
204         return output;
205     }
206 
207     public void sm4_setkey_dec(SM4_Context ctx, byte[] key) throws Exception {
208         if (ctx == null) {
209             throw new Exception("ctx is null!");
210         }
211 
212         if (key == null || key.length != 16) {
213             throw new Exception("key error!");
214         }
215 
216         int i = 0;
217         ctx.mode = SM4_DECRYPT;
218         sm4_setkey(ctx.sk, key);
219         for (i = 0; i < 16; i++) {
220             SWAP(ctx.sk, i);
221         }
222     }
223 
224     private void SWAP(int[] sk, int i) {
225         int t = sk[i];
226         sk[i] = sk[(31 - i)];
227         sk[(31 - i)] = t;
228     }
229 
230     public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) throws Exception {
231         if (iv == null || iv.length != 16) {
232             throw new Exception("iv error!");
233         }
234 
235         if (input == null) {
236             throw new Exception("input is null!");
237         }
238 
239         if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) {
240             input = padding(input, SM4_ENCRYPT);
241         }
242 
243         int i = 0;
244         int length = input.length;
245         ByteArrayInputStream bins = new ByteArrayInputStream(input);
246         ByteArrayOutputStream bous = new ByteArrayOutputStream();
247         if (ctx.mode == SM4_ENCRYPT) {
248             for (; length > 0; length -= 16) {
249                 byte[] in = new byte[16];
250                 byte[] out = new byte[16];
251                 byte[] out1 = new byte[16];
252 
253                 bins.read(in);
254                 for (i = 0; i < 16; i++) {
255                     out[i] = ((byte) (in[i] ^ iv[i]));
256                 }
257                 sm4_one_round(ctx.sk, out, out1);
258                 System.arraycopy(out1, 0, iv, 0, 16);
259                 bous.write(out1);
260             }
261         } else {
262             byte[] temp = new byte[16];
263             for (; length > 0; length -= 16) {
264                 byte[] in = new byte[16];
265                 byte[] out = new byte[16];
266                 byte[] out1 = new byte[16];
267 
268                 bins.read(in);
269                 System.arraycopy(in, 0, temp, 0, 16);
270                 sm4_one_round(ctx.sk, in, out);
271                 for (i = 0; i < 16; i++) {
272                     out1[i] = ((byte) (out[i] ^ iv[i]));
273                 }
274                 System.arraycopy(temp, 0, iv, 0, 16);
275                 bous.write(out1);
276             }
277         }
278 
279         byte[] output = bous.toByteArray();
280         if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
281             output = padding(output, SM4_DECRYPT);
282         }
283         bins.close();
284         bous.close();
285         return output;
286     }
287 
288 }

 

SM4_Context.java

 1 package cn.com.sinosoft.cas.util.sm4;
 2 
 3 /**
 4 * SM4 encryption and decryption
 5  * @author wzk
 6  *
 7  */
 8 public class SM4_Context {
 9     public int mode;
10 
11     public int[] sk;
12 
13     public boolean isPadding;
14 
15     public SM4_Context() {
16         this.mode = 1;
17         this.isPadding = true;
18         this.sk = new int[32];
19     }
20 }

 

Util.java

  1 package cn.com.sinosoft.cas.util.sm4;
  2 
  3 import java.math.BigInteger;
  4 
  5 /**
  6 * SM4 encryption and decryption tool class
  7  * @author wzk
  8  *
  9  */
 10 public class Util {
 11     /**
 12 * shaping and converting into byte stream (byte array) data transmitted by the network
 13      *
 14      * @param num
 15 * one integer data
 16 * @ return 4-byte array
 17      */
 18     public static byte[] intToBytes(int num) {
 19         byte[] bytes = new byte[4];
 20         bytes[0] = (byte) (0xff & (num >> 0));
 21         bytes[1] = (byte) (0xff & (num >> 8));
 22         bytes[2] = (byte) (0xff & (num >> 16));
 23         bytes[3] = (byte) (0xff & (num >> 24));
 24         return bytes;
 25     }
 26 
 27     /**
 28 * convert four bytes of byte data into an integer data
 29      *
 30      * @param bytes
 31 * 4-byte byte array
 32 * @ return an integer data
 33      */
 34     public static int byteToInt(byte[] bytes) {
 35         int num = 0;
 36         int temp;
 37         temp = (0x000000ff & (bytes[0])) << 0;
 38         num = num | temp;
 39         temp = (0x000000ff & (bytes[1])) << 8;
 40         num = num | temp;
 41         temp = (0x000000ff & (bytes[2])) << 16;
 42         num = num | temp;
 43         temp = (0x000000ff & (bytes[3])) << 24;
 44         num = num | temp;
 45         return num;
 46     }
 47 
 48     /**
 49 * long shaping is converted into byte stream (byte array) data transmitted over the network
 50      *
 51      * @param num
 52 * one long integer data
 53 * @ return 4-byte array
 54      */
 55     public static byte[] longToBytes(long num) {
 56         byte[] bytes = new byte[8];
 57         for (int i = 0; i < 8; i++) {
 58             bytes[i] = (byte) (0xff & (num >> (i * 8)));
 59         }
 60 
 61         return bytes;
 62     }
 63 
 64     /**
 65 * large number conversion byte stream (byte array) data
 66      *
 67      * @param n
 68      * @return
 69      */
 70     public static byte[] byteConvert32Bytes(BigInteger n) {
 71         byte tmpd[] = (byte[]) null;
 72         if (n == null) {
 73             return null;
 74         }
 75 
 76         if (n.toByteArray().length == 33) {
 77             tmpd = new byte[32];
 78             System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);
 79         } else if (n.toByteArray().length == 32) {
 80             tmpd = n.toByteArray();
 81         } else {
 82             tmpd = new byte[32];
 83             for (int i = 0; i < 32 - n.toByteArray().length; i++) {
 84                 tmpd[i] = 0;
 85             }
 86             System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);
 87         }
 88         return tmpd;
 89     }
 90 
 91     /**
 92 * convert byte stream (byte array) data to large number
 93      *
 94      * @param b
 95      * @return
 96      */
 97     public static BigInteger byteConvertInteger(byte[] b) {
 98         if (b[0] < 0) {
 99             byte[] temp = new byte[b.length + 1];
100             temp[0] = 0;
101             System.arraycopy(b, 0, temp, 1, b.length);
102             return new BigInteger(temp);
103         }
104         return new BigInteger(b);
105     }
106 
107     /**
108 * get value from byte array (hexadecimal digit)
109      *
110      * @param bytes
111      * @return
112      */
113     public static String getHexString(byte[] bytes) {
114         return getHexString(bytes, true);
115     }
116 
117     /**
118 * get value from byte array (hexadecimal digit)
119      *
120      * @param bytes
121      * @param upperCase
122      * @return
123      */
124     public static String getHexString(byte[] bytes, boolean upperCase) {
125         String ret = "";
126         for (int i = 0; i < bytes.length; i++) {
127             ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);
128         }
129         return upperCase ? ret.toUpperCase() : ret;
130     }
131 
132     /**
133 * print hex string
134      *
135      * @param bytes
136      */
137     public static void printHexString(byte[] bytes) {
138         for (int i = 0; i < bytes.length; i++) {
139             String hex = Integer.toHexString(bytes[i] & 0xFF);
140             if (hex.length() == 1) {
141                 hex = '0' + hex;
142             }
143             System.out.print("0x" + hex.toUpperCase() + ",");
144         }
145         System.out.println("");
146     }
147 
148     /**
149      * Convert hex string to byte[]
150      *
151      * @param hexString
152      *            the hex string
153      * @return byte[]
154      */
155     public static byte[] hexStringToBytes(String hexString) {
156         if (hexString == null || hexString.equals("")) {
157             return null;
158         }
159 
160         hexString = hexString.toUpperCase();
161         int length = hexString.length() / 2;
162         char[] hexChars = hexString.toCharArray();
163         byte[] d = new byte[length];
164         for (int i = 0; i < length; i++) {
165             int pos = i * 2;
166             d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
167         }
168         return d;
169     }
170 
171     /**
172      * Convert char to byte
173      *
174      * @param c
175      *            char
176      * @return byte
177      */
178     public static byte charToByte(char c) {
179         return (byte) "0123456789ABCDEF".indexOf(c);
180     }
181 
182     /**
183 * lowercase character array used to establish the output of hexadecimal characters
184      */
185     private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
186             'e', 'f' };
187 
188     /**
189 * uppercase character array used to establish the output of hexadecimal characters
190      */
191     private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
192             'E', 'F' };
193 
194     /**
195 * convert byte array to hexadecimal character array
196      *
197      * @param data
198      *            byte[]
199 * @ return hex char []
200      */
201     public static char[] encodeHex(byte[] data) {
202         return encodeHex(data, true);
203     }
204 
205     /**
206 * convert byte array to hexadecimal character array
207      *
208      * @param data
209      *            byte[]
210      * @param toLowerCase
 211 * < code > true < / code > is converted to lowercase format, < code > false < / code > is converted to uppercase format
 212 * @ return hex char []
213      */
214     public static char[] encodeHex(byte[] data, boolean toLowerCase) {
215         return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
216     }
217 
218     /**
219 * convert byte array to hexadecimal character array
220      *
221      * @param data
222      *            byte[]
223      * @param toDigits
 224 * char [] for control output
 225 * @ return hex char []
226      */
227     protected static char[] encodeHex(byte[] data, char[] toDigits) {
228         int l = data.length;
229         char[] out = new char[l << 1];
230         // two characters form the hex value.
231         for (int i = 0, j = 0; i < l; i++) {
232             out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
233             out[j++] = toDigits[0x0F & data[i]];
234         }
235         return out;
236     }
237 
238     /**
239 * convert byte array to hexadecimal string
240      *
241      * @param data
242      *            byte[]
243 * @ return hex String
244      */
245     public static String encodeHexString(byte[] data) {
246         return encodeHexString(data, true);
247     }
248 
249     /**
250 * convert byte array to hexadecimal string
251      *
252      * @param data
253      *            byte[]
254      * @param toLowerCase
 255 * < code > true < / code > is converted to lowercase format, < code > false < / code > is converted to uppercase format
 256 * @ return hex String
257      */
258     public static String encodeHexString(byte[] data, boolean toLowerCase) {
259         return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
260     }
261 
262     /**
263 * convert byte array to hexadecimal string
264      *
265      * @param data
266      *            byte[]
267      * @param toDigits
 268 * char [] for control output
 269 * @ return hex String
270      */
271     protected static String encodeHexString(byte[] data, char[] toDigits) {
272         return new String(encodeHex(data, toDigits));
273     }
274 
275     /**
276 * convert hexadecimal character array to byte array
277      *
278      * @param data
 279 * hex char []
280      * @return byte[]
281      * @throws RuntimeException
 282 * if the source hexadecimal character array is an odd length, a runtime exception will be thrown
283      */
284     public static byte[] decodeHex(char[] data) {
285         int len = data.length;
286 
287         if ((len & 0x01) != 0) {
288             throw new RuntimeException("Odd number of characters.");
289         }
290 
291         byte[] out = new byte[len >> 1];
292 
293         // two characters form the hex value.
294         for (int i = 0, j = 0; j < len; i++) {
295             int f = toDigit(data[j], j) << 4;
296             j++;
297             f = f | toDigit(data[j], j);
298             j++;
299             out[i] = (byte) (f & 0xFF);
300         }
301 
302         return out;
303     }
304 
305     /**
306 * converts hexadecimal characters to an integer
307      *
308      * @param ch
 309 * hex char
310      * @param index
 311 * position of hexadecimal characters in character array
 312 * @ return an integer
313      * @throws RuntimeException
 314 * throw a runtime exception when ch is not a legal hexadecimal character
315      */
316     protected static int toDigit(char ch, int index) {
317         int digit = Character.digit(ch, 16);
318         if (digit == -1) {
319             throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
320         }
321         return digit;
322     }
323 
324     /**
325 * numeric string to ASCII string
326      *
327      * @param String
 328 * string
 329 * @ return ascii string
330      */
331     public static String StringToAsciiString(String content) {
332         String result = "";
333         int max = content.length();
334         for (int i = 0; i < max; i++) {
335             char c = content.charAt(i);
336             String b = Integer.toHexString(c);
337             result = result + b;
338         }
339         return result;
340     }
341 
342     /**
343 * hex to string
344      *
345      * @param hexString
 346 * hexadecimal string
347      * @param encodeType
 348 * encoding type 4: Unicode, 2: normal encoding
 349 * @ return string
350      */
351     public static String hexStringToString(String hexString, int encodeType) {
352         String result = "";
353         int max = hexString.length() / encodeType;
354         for (int i = 0; i < max; i++) {
355             char c = (char) hexStringToAlgorism(hexString.substring(i * encodeType, (i + 1) * encodeType));
356             result += c;
357         }
358         return result;
359     }
360 
361     /**
362 * hexadecimal string packed decimal
363      *
364      * @param hex
 365 * hex string
 366 * @ return decimal value
367      */
368     public static int hexStringToAlgorism(String hex) {
369         hex = hex.toUpperCase();
370         int max = hex.length();
371         int result = 0;
372         for (int i = max; i > 0; i--) {
373             char c = hex.charAt(i - 1);
374             int algorism = 0;
375             if (c >= '0' && c <= '9') {
376                 algorism = c - '0';
377             } else {
378                 algorism = c - 55;
379             }
380             result += Math.pow(16, max - i) * algorism;
381         }
382         return result;
383     }
384 
385     /**
386 * 16 to binary
387      *
388      * @param hex
 389 * hex string
 390 * @ return binary string
391      */
392     public static String hexStringToBinary(String hex) {
393         hex = hex.toUpperCase();
394         String result = "";
395         int max = hex.length();
396         for (int i = 0; i < max; i++) {
397             char c = hex.charAt(i);
398             switch (c) {
399             case '0':
400                 result += "0000";
401                 break;
402             case '1':
403                 result += "0001";
404                 break;
405             case '2':
406                 result += "0010";
407                 break;
408             case '3':
409                 result += "0011";
410                 break;
411             case '4':
412                 result += "0100";
413                 break;
414             case '5':
415                 result += "0101";
416                 break;
417             case '6':
418                 result += "0110";
419                 break;
420             case '7':
421                 result += "0111";
422                 break;
423             case '8':
424                 result += "1000";
425                 break;
426             case '9':
427                 result += "1001";
428                 break;
429             case 'A':
430                 result += "1010";
431                 break;
432             case 'B':
433                 result += "1011";
434                 break;
435             case 'C':
436                 result += "1100";
437                 break;
438             case 'D':
439                 result += "1101";
440                 break;
441             case 'E':
442                 result += "1110";
443                 break;
444             case 'F':
445                 result += "1111";
446                 break;
447             }
448         }
449         return result;
450     }
451 
452     /**
453 * ascii string to numeric string
454      *
455      * @param String
 456 * ascii string
 457 * @ return string
458      */
459     public static String AsciiStringToString(String content) {
460         String result = "";
461         int length = content.length() / 2;
462         for (int i = 0; i < length; i++) {
463             String c = content.substring(i * 2, i * 2 + 2);
464             int a = hexStringToAlgorism(c);
465             char b = (char) a;
466             String d = String.valueOf(b);
467             result += d;
468         }
469         return result;
470     }
471 
472     /**
473 * converts decimal to a hexadecimal string of the specified length
474      *
475      * @param algorism
 476 * int decimal digits
477      * @param maxLength
 478 * hexadecimal string length after int conversion
 479 * @ return string hexadecimal string after conversion
480      */
481     public static String algorismToHexString(int algorism, int maxLength) {
482         String result = "";
483         result = Integer.toHexString(algorism);
484 
485         if (result.length() % 2 == 1) {
486             result = "0" + result;
487         }
488         return patchHexString(result.toUpperCase(), maxLength);
489     }
490 
491     /**
492 * byte array to normal string (ASCII corresponding character)
493      *
494      * @param bytearray
495      *            byte[]
496      * @return String
497      */
498     public static String byteToString(byte[] bytearray) {
499         String result = "";
500         char temp;
501 
502         int length = bytearray.length;
503         for (int i = 0; i < length; i++) {
504             temp = (char) bytearray[i];
505             result += temp;
506         }
507         return result;
508     }
509 
510     /**
511 * binary string to decimal
512      *
513      * @param binary
 514 * binary string
 515 * @ return decimal value
516      */
517     public static int binaryToAlgorism(String binary) {
518         int max = binary.length();
519         int result = 0;
520         for (int i = max; i > 0; i--) {
521             char c = binary.charAt(i - 1);
522             int algorism = c - '0';
523             result += Math.pow(2, max - i) * algorism;
524         }
525         return result;
526     }
527 
528     /**
529 * convert decimal to hexadecimal string
530      *
531      * @param algorism
 532 * int decimal number
 533 * @ return string hexadecimal string
534      */
535     public static String algorismToHEXString(int algorism) {
536         String result = "";
537         result = Integer.toHexString(algorism);
538 
539         if (result.length() % 2 == 1) {
540             result = "0" + result;
541 
542         }
543         result = result.toUpperCase();
544 
545         return result;
546     }
547 
548     /**
549 * hex string is preceded by 0, which is mainly used for insufficient length digits.
550      *
551      * @param str
 552 * string hexadecimal string with supplementary length required
553      * @param maxLength
 554 * int length of hexadecimal string after complement
 555 * @ return supplementary result
556      */
557     static public String patchHexString(String str, int maxLength) {
558         String temp = "";
559         for (int i = 0; i < maxLength - str.length(); i++) {
560             temp = "0" + temp;
561         }
562         str = (temp + str).substring(0, maxLength);
563         return str;
564     }
565 
566     /**
567 * convert a string to int
568      *
569      * @param s
 570 * string string to convert
571      * @param defaultInt
 572 * int if an exception occurs, the number returned by default
573      * @param radix
 574 * int what is the base of the string to be converted, such as 16 8 10
 575 * @ return int converted number
576      */
577     public static int parseToInt(String s, int defaultInt, int radix) {
578         int i = 0;
579         try {
580             i = Integer.parseInt(s, radix);
581         } catch (NumberFormatException ex) {
582             i = defaultInt;
583         }
584         return i;
585     }
586 
587     /**
588 * converts a decimal numeric string to int
589      *
590      * @param s
 591 * string the string to convert
592      * @param defaultInt
 593 * int if an exception occurs, the number returned by default
 594 * @ return int converted number
595      */
596     public static int parseToInt(String s, int defaultInt) {
597         int i = 0;
598         try {
599             i = Integer.parseInt(s);
600         } catch (NumberFormatException ex) {
601             i = defaultInt;
602         }
603         return i;
604     }
605 
606     /**
607 * convert hex string to byte array
608      *
609      * @return the array of byte
610      */
611     public static byte[] hexToByte(String hex) throws IllegalArgumentException {
612         if (hex.length() % 2 != 0) {
613             throw new IllegalArgumentException();
614         }
615         char[] arr = hex.toCharArray();
616         byte[] b = new byte[hex.length() / 2];
617         for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
618             String swap = "" + arr[i++] + arr[i];
619             int byteint = Integer.parseInt(swap, 16) & 0xFF;
620             b[j] = new Integer(byteint).byteValue();
621         }
622         return b;
623     }
624 
625     /**
626 * byte array converted to hexadecimal string
627      *
628      * @param b
 629 * byte [] byte array to be converted
 630 * @ return string hex string
631      */
632     public static String byteToHex(byte b[]) {
633         if (b == null) {
634             throw new IllegalArgumentException("Argument b ( byte array ) is null! ");
635         }
636         String hs = "";
637         String stmp = "";
638         for (int n = 0; n < b.length; n++) {
639             stmp = Integer.toHexString(b[n] & 0xff);
640             if (stmp.length() == 1) {
641                 hs = hs + "0" + stmp;
642             } else {
643                 hs = hs + stmp;
644             }
645         }
646         return hs.toUpperCase();
647     }
648 
649     public static byte[] subByte(byte[] input, int startIndex, int length) {
650         byte[] bt = new byte[length];
651         for (int i = 0; i < length; i++) {
652             bt[i] = input[i + startIndex];
653         }
654         return bt;
655     }
656 }

 

SM4Utils.java

package cn.com.sinosoft.cas.util.sm4;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**

  • sm4 encryption and decryption
  • CBC and ECB modes
  • @author wzk

/
@SuppressWarnings("restriction")
public class SM4Utils {
/**
*Consistent with the front-end key
/
private static String secretKey = "11sade343f";
/**
*Consistent with front-end iv
*/
private static String iv = "3evfgt65334";

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> String UTF_8 = "UTF-8"<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span> hexString = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> SM4Utils() {
}
</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > ECB mode encryption</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String encryptData_ECB(String plainText) {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_ENCRYPT;

        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
        keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> secretKey.getBytes();
        SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        sm4.sm4_setkey_enc(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_ecb(ctx, plainText.getBytes(UTF_8));
        String cipherText </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BASE64Encoder().encode(encrypted);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (cipherText != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; cipherText.trim().length() &gt; 0<span style="color: rgba(0, 0, 0, 1)">) {
            Pattern p </span>= Pattern.compile("\\s*|\t|\r|\n"<span style="color: rgba(0, 0, 0, 1)">);
            Matcher m </span>=<span style="color: rgba(0, 0, 0, 1)"> p.matcher(cipherText);
            cipherText </span>= m.replaceAll(""<span style="color: rgba(0, 0, 0, 1)">);
        }
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}
</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > ECB mode decryption</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String decryptData_ECB(String cipherText) {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_DECRYPT;

        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
        keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> secretKey.getBytes();
        SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        sm4.sm4_setkey_dec(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted = sm4.sm4_crypt_ecb(ctx, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BASE64Decoder().decodeBuffer(cipherText));
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String(decrypted, UTF_8);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}
</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > CBC mode encryption</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String encryptData_CBC(String plainText) {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_ENCRYPT;

        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] ivBytes;

        keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> secretKey.getBytes();
        ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> iv.getBytes();

        SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        sm4.sm4_setkey_enc(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes(UTF_8));
        String cipherText </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BASE64Encoder().encode(encrypted);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (cipherText != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; cipherText.trim().length() &gt; 0<span style="color: rgba(0, 0, 0, 1)">) {
            Pattern p </span>= Pattern.compile("\\s*|\t|\r|\n"<span style="color: rgba(0, 0, 0, 1)">);
            Matcher m </span>=<span style="color: rgba(0, 0, 0, 1)"> p.matcher(cipherText);
            cipherText </span>= m.replaceAll(""<span style="color: rgba(0, 0, 0, 1)">);
        }
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cipherText;
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}
</span><span style="color: rgba(0, 128, 0, 1)">//< / span > < span style = "color: RGBA (0, 128, 0, 1)" > CBC mode decryption</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String decryptData_CBC(String cipherText) {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        SM4_Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4_Context();
        ctx.isPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
        ctx.mode </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4.SM4_DECRYPT;

        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] keyBytes;
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] ivBytes;
        </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (hexString) {
            keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Util.hexStringToBytes(secretKey);
            ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> Util.hexStringToBytes(iv);
        } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
            keyBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> secretKey.getBytes();
            ivBytes </span>=<span style="color: rgba(0, 0, 0, 1)"> iv.getBytes();
        }

        SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
        sm4.sm4_setkey_dec(ctx, keyBytes);
        </span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BASE64Decoder().decodeBuffer(cipherText));
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String(decrypted, UTF_8);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> UnsupportedEncodingException {
    String plainText </span>= "Zhongke soft"<span style="color: rgba(0, 0, 0, 1)">;
    
    String cipherText </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4Utils.encryptData_ECB(plainText);
    System.out.println(</span>"ECB Pattern encryption ciphertext: " +<span style="color: rgba(0, 0, 0, 1)"> cipherText);
    
    plainText </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4Utils.decryptData_ECB(cipherText);
    System.out.println(</span>"ECB Mode decryption plaintext: " +<span style="color: rgba(0, 0, 0, 1)"> plainText);

    cipherText </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4Utils.encryptData_CBC(plainText);
    System.out.println(</span>"CBC Pattern encryption ciphertext: " +<span style="color: rgba(0, 0, 0, 1)"> cipherText);
    
    plainText </span>=<span style="color: rgba(0, 0, 0, 1)"> SM4Utils.decryptData_CBC(cipherText);
    System.out.println(</span>"CBC Mode decryption plaintext: " +<span style="color: rgba(0, 0, 0, 1)"> plainText);

}

}

III. test

1. CBC mode (double salt, safer)
front end:
var sm4=new SM4Util();
sm4.encryptData_CBC('');

Back end:
SM4Utils.decryptData_CBC("");

2. ECB mode
front end:
var sm4=new SM4Util();
sm4.encryptData_ECB('');

Back end:
SM4Utils.decryptData_ECB("");

 

Topics: Java Javascript Front-end