zoukankan      html  css  js  c++  java
  • 国密 sm4 js 加密, java解密

    sm4.js

    /**
     * base64js
     */
    /**
     * base64js
     * base64js.toByteArray(d.input)
     * base64js.fromByteArray(c);
     * @author c.z.s
     * @email 1048829253@qq.com
     * @company
     * @date 2018-07
     *
     */
    (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 c.z.s
     * @email 1048829253@qq.com
     * @company GDT-ZWZX-DEV-PT
     * @date 2018-07
     */
    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;
            }
            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() {
        this.secretKey="11HDESaAhiHHugDz";
        this.iv = "";
        this.hexString = false;
    
        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*|	|
    |
    )/g, "");
                }
                return cipherText;
            }catch (e){
                console.error(e);
                return null;
            }
    
        }
    
        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*|	|
    |
    )/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);
                }
            }
            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;
        }
    };
    

      SM4.java

    package com.ruoyi.common.utils;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    
    public class SM4
    {
    	public static final int SM4_ENCRYPT = 1;
    
    	public static final int SM4_DECRYPT = 0;
    
    	private int GET_ULONG_BE(byte[] b, int i)
    	{
    		int n = (int)(b[i] & 0xff) << 24 | (int)((b[i + 1] & 0xff) << 16) | (int)((b[i + 2] & 0xff) << 8) | (int)(b[i + 3] & 0xff) & 0xffffffff;
    		return n;
    	}
    
    	private void PUT_ULONG_BE(int n, byte[] b, int i)
    	{
    		b[i] = (byte)(int)(0xFF & n >> 24);
    		b[i + 1] = (byte)(int)(0xFF & n >> 16);
    		b[i + 2] = (byte)(int)(0xFF & n >> 8);
    		b[i + 3] = (byte)(int)(0xFF & n);
    	}
    
    	private int SHL(int x, int n)
    	{
    		return (x & 0xFFFFFFFF) << n;
    	}
    
    	private int ROTL(int x, int n)
    	{
    		return SHL(x, n) | x >> (32 - n);
    	}
    
    	public static final byte[] SboxTable = { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe,
    			(byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6,
    			0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67,
    			(byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3,
    			(byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06,
    			(byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91,
    			(byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,
    			(byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4,
    			(byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8,
    			(byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa,
    			0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7,
    			(byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83,
    			0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8,
    			0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda,
    			(byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56,
    			(byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1,
    			(byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87,
    			(byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27,
    			0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4,
    			(byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a,
    			(byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3,
    			(byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15,
    			(byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4,
    			(byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32,
    			0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d,
    			(byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca,
    			0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f,
    			(byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd,
    			(byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b,
    			0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb,
    			(byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41,
    			0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31,
    			(byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d,
    			0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4,
    			(byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c,
    			(byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09,
    			(byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0,
    			0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79,
    			(byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 };
    
    	public static final int[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
    
    	public static final int[] 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 };
    
    	private byte sm4Sbox(byte inch)
    	{
    		int i = inch & 0xFF;
    		byte retVal = SboxTable[i];
    		return retVal;
    	}
    
    	private int sm4Lt(int ka)
    	{
    		int bb = 0;
    		int c = 0;
    		byte[] a = new byte[4];
    		byte[] b = new byte[4];
    		PUT_ULONG_BE(ka, a, 0);
    		b[0] = sm4Sbox(a[0]);
    		b[1] = sm4Sbox(a[1]);
    		b[2] = sm4Sbox(a[2]);
    		b[3] = sm4Sbox(a[3]);
    		bb = GET_ULONG_BE(b, 0);
    		c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);
    		return c;
    	}
    
    	private int sm4F(int x0, int x1, int x2, int x3, int rk)
    	{
    		return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);
    	}
    
    	private int sm4CalciRK(int ka)
    	{
    		int bb = 0;
    		int rk = 0;
    		byte[] a = new byte[4];
    		byte[] b = new byte[4];
    		PUT_ULONG_BE(ka, a, 0);
    		b[0] = sm4Sbox(a[0]);
    		b[1] = sm4Sbox(a[1]);
    		b[2] = sm4Sbox(a[2]);
    		b[3] = sm4Sbox(a[3]);
    		bb = GET_ULONG_BE(b, 0);
    		rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);
    		return rk;
    	}
    
    	private void sm4_setkey(int[] SK, byte[] key)
    	{
    		int[] MK = new int[4];
    		int[] k = new int[36];
    		int i = 0;
    		MK[0] = GET_ULONG_BE(key, 0);
    		MK[1] = GET_ULONG_BE(key, 4);
    		MK[2] = GET_ULONG_BE(key, 8);
    		MK[3] = GET_ULONG_BE(key, 12);
    		k[0] = MK[0] ^ (int) FK[0];
    		k[1] = MK[1] ^ (int) FK[1];
    		k[2] = MK[2] ^ (int) FK[2];
    		k[3] = MK[3] ^ (int) FK[3];
    		for (; i < 32; i++)
    		{
    			k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (int) CK[i]));
    			SK[i] = k[(i + 4)];
    		}
    	}
    
    	private void sm4_one_round(int[] sk, byte[] input, byte[] output)
    	{
    		int i = 0;
    		int[] ulbuf = new int[36];
    		ulbuf[0] = GET_ULONG_BE(input, 0);
    		ulbuf[1] = GET_ULONG_BE(input, 4);
    		ulbuf[2] = GET_ULONG_BE(input, 8);
    		ulbuf[3] = GET_ULONG_BE(input, 12);
    		while (i < 32)
    		{
    			ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);
    			i++;
    		}
    		PUT_ULONG_BE(ulbuf[35], output, 0);
    		PUT_ULONG_BE(ulbuf[34], output, 4);
    		PUT_ULONG_BE(ulbuf[33], output, 8);
    		PUT_ULONG_BE(ulbuf[32], output, 12);
    	}
    
    	private byte[] padding(byte[] input, int mode)
    	{
    		if (input == null)
    		{
    			return null;
    		}
    
    		byte[] ret = (byte[]) null;
    		if (mode == SM4_ENCRYPT)
    		{
    			int p = 16 - input.length % 16;
    			ret = new byte[input.length + p];
    			System.arraycopy(input, 0, ret, 0, input.length);
    			for (int i = 0; i < p; i++)
    			{
    				ret[input.length + i] = (byte) p;
    			}
    		}
    		else
    		{
    			int p = input[input.length - 1];
    			ret = new byte[input.length - p];
    			System.arraycopy(input, 0, ret, 0, input.length - p);
    		}
    		return ret;
    	}
    
    	public void sm4_setkey_enc(SM4_Context ctx, byte[] key) throws Exception
    	{
    		if (ctx == null)
    		{
    			throw new Exception("ctx is null!");
    		}
    
    		if (key == null || key.length != 16)
    		{
    			throw new Exception("key error!");
    		}
    
    		ctx.mode = SM4_ENCRYPT;
    		sm4_setkey(ctx.sk, key);
    	}
    
    
    	public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) throws Exception
    	{
    		if (input == null)
    		{
    			throw new Exception("input is null!");
    		}
    
    		if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT))
    		{
    			input = padding(input, SM4_ENCRYPT);
    		}
    
    		int length = input.length;
    		ByteArrayInputStream bins = new ByteArrayInputStream(input);
    		ByteArrayOutputStream bous = new ByteArrayOutputStream();
    		for(; length > 0; length -= 16)
    		{
    			byte[] in = new byte[16];
    			byte[] out = new byte[16];
    			bins.read(in);
    			sm4_one_round(ctx.sk, in, out);
    			bous.write(out);
    		}
    
    		byte[] output = bous.toByteArray();
    		if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
    		{
    			output = padding(output, SM4_DECRYPT);
    		}
    		bins.close();
    		bous.close();
    		return output;
    	}
    
    
    	public void sm4_setkey_dec(SM4_Context ctx, byte[] key) throws Exception
    	{
    		if (ctx == null)
    		{
    			throw new Exception("ctx is null!");
    		}
    
    		if (key == null || key.length != 16)
    		{
    			throw new Exception("key error!");
    		}
    
    		int i = 0;
    		ctx.mode = SM4_DECRYPT;
    		sm4_setkey(ctx.sk, key);
    		for (i = 0; i < 16; i++)
    		{
    			SWAP(ctx.sk, i);
    		}
    	}
    
    
    
    	private void SWAP(int[] sk, int i)
    	{
    		int t = sk[i];
    		sk[i] = sk[(31 - i)];
    		sk[(31 - i)] = t;
    	}
    
    
    
    
    	public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) throws Exception
    	{
    		if (iv == null || iv.length != 16)
    		{
    			throw new Exception("iv error!");
    		}
    
    		if (input == null)
    		{
    			throw new Exception("input is null!");
    		}
    
    		if (ctx.isPadding && ctx.mode == SM4_ENCRYPT)
    		{
    			input = padding(input, SM4_ENCRYPT);
    		}
    
    		int i = 0;
    		int length = input.length;
    		ByteArrayInputStream bins = new ByteArrayInputStream(input);
    		ByteArrayOutputStream bous = new ByteArrayOutputStream();
    		if (ctx.mode == SM4_ENCRYPT)
    		{
    			for(; length > 0; length -= 16)
    			{
    				byte[] in = new byte[16];
    				byte[] out = new byte[16];
    				byte[] out1 = new byte[16];
    
    				bins.read(in);
    				for (i = 0; i < 16; i++)
    				{
    					out[i] = ((byte) (in[i] ^ iv[i]));
    				}
    				sm4_one_round(ctx.sk, out, out1);
    				System.arraycopy(out1, 0, iv, 0, 16);
    				bous.write(out1);
    			}
    		}
    		else
    		{
    			byte[] temp = new byte[16];
    			for(; length > 0; length -= 16)
    			{
    				byte[] in = new byte[16];
    				byte[] out = new byte[16];
    				byte[] out1 = new byte[16];
    
    				bins.read(in);
    				System.arraycopy(in, 0, temp, 0, 16);
    				sm4_one_round(ctx.sk, in, out);
    				for (i = 0; i < 16; i++)
    				{
    					out1[i] = ((byte) (out[i] ^ iv[i]));
    				}
    				System.arraycopy(temp, 0, iv, 0, 16);
    				bous.write(out1);
    			}
    		}
    
    		byte[] output = bous.toByteArray();
    		if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
    		{
    			output = padding(output, SM4_DECRYPT);
    		}
    		bins.close();
    		bous.close();
    		return output;
    	}
    
    
    
    }
    

      

    SM4_Context.java
    package com.ruoyi.common.utils;
    
    public class SM4_Context
    {
    	public int mode;
    
    	public int[] sk;
    
    	public boolean isPadding;
    
    	public SM4_Context()
    	{
    		this.mode = 1;
    		this.isPadding = true;
    		this.sk = new int[32];
    	}
    }
    

      

    SM4Utils.java
    package com.ruoyi.common.utils;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    import java.io.UnsupportedEncodingException;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class SM4Utils
    {
    	private String secretKey = "";
    	private String iv = "";
    	private boolean hexString = false;
    
    	public SM4Utils()
    	{
    	}
    
    	public String encryptData_ECB(String plainText)
    	{
    		try
    		{
    			SM4_Context ctx = new SM4_Context();
    			ctx.isPadding = true;
    			ctx.mode = SM4.SM4_ENCRYPT;
    
    			byte[] keyBytes;
    			keyBytes = secretKey.getBytes();
    			SM4 sm4 = new SM4();
    			sm4.sm4_setkey_enc(ctx, keyBytes);
    			byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8"));
    			String cipherText = new BASE64Encoder().encode(encrypted);
    			if (cipherText != null && cipherText.trim().length() > 0)
    			{
    				Pattern p = Pattern.compile("\s*|	|
    |
    ");
    				Matcher m = p.matcher(cipherText);
    				cipherText = m.replaceAll("");
    			}
    			return cipherText;
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	public String decryptData_ECB(String cipherText)
    	{
    		try
    		{
    			SM4_Context ctx = new SM4_Context();
    			ctx.isPadding = true;
    			ctx.mode = SM4.SM4_DECRYPT;
    
    			byte[] keyBytes;
    			keyBytes = secretKey.getBytes();
    			SM4 sm4 = new SM4();
    			sm4.sm4_setkey_dec(ctx, keyBytes);
    			byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText));
    			return new String(decrypted, "UTF-8");
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	public String encryptData_CBC(String plainText){
    		try{
    			SM4_Context ctx = new SM4_Context();
    			ctx.isPadding = true;
    			ctx.mode = SM4.SM4_ENCRYPT;
    
    			byte[] keyBytes;
    			byte[] ivBytes;
    
    			keyBytes = secretKey.getBytes();
    			ivBytes = iv.getBytes();
    
    			SM4 sm4 = new SM4();
    			sm4.sm4_setkey_enc(ctx, keyBytes);
    			byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8"));
    			String cipherText = new BASE64Encoder().encode(encrypted);
    			if (cipherText != null && cipherText.trim().length() > 0)
    			{
    				Pattern p = Pattern.compile("\s*|	|
    |
    ");
    				Matcher m = p.matcher(cipherText);
    				cipherText = m.replaceAll("");
    			}
    			return cipherText;
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	public String decryptData_CBC(String cipherText)
    	{
    		try
    		{
    			SM4_Context ctx = new SM4_Context();
    			ctx.isPadding = true;
    			ctx.mode = SM4.SM4_DECRYPT;
    
    			byte[] keyBytes;
    			byte[] ivBytes;
    			if (hexString)
    			{
    				keyBytes = Util.hexStringToBytes(secretKey);
    				ivBytes = Util.hexStringToBytes(iv);
    			}
    			else
    			{
    				keyBytes = secretKey.getBytes();
    				ivBytes = iv.getBytes();
    			}
    
    			SM4 sm4 = new SM4();
    			sm4.sm4_setkey_dec(ctx, keyBytes);
    			byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));
    			return new String(decrypted, "UTF-8");
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    	public String getSecretKey() {
    		return secretKey;
    	}
    
    	public void setSecretKey(String secretKey) {
    		this.secretKey = secretKey;
    	}
    
    	public String getIv() {
    		return iv;
    	}
    
    	public void setIv(String iv) {
    		this.iv = iv;
    	}
    
    	public static void main(String[] args) throws UnsupportedEncodingException {
    		String plainText ="ssda撒了ii&$$^##)*&6223';.,[]";
    		SM4Utils sm4 = new SM4Utils();
    		sm4.secretKey = "11HDESaAhiHHugDz";
    		sm4.iv = "";
    		plainText.getBytes("UTF-8");
    		System.out.println("ECB模式");
    		String cipherText = sm4.encryptData_ECB(plainText);
    		System.out.println("密文: " + cipherText);
    		System.out.println("");
    
    		plainText = sm4.decryptData_ECB(cipherText);
    		System.out.println("明文: " + plainText);
    		System.out.println("");
    
    		System.out.println("CBC模式");
    		sm4.iv = "UISwD9fW6cFh9SNS";
    		cipherText = sm4.encryptData_CBC(plainText);
    		System.out.println("密文: " + cipherText);
    		System.out.println("");
    
    		plainText = sm4.decryptData_CBC(cipherText);
    		System.out.println("明文: " + plainText);
    
    
    	}
    
    }
    

      

  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/joyny/p/12807941.html
Copyright © 2011-2022 走看看