精华内容
下载资源
问答
  • SM4Utils sm4 = new SM4Utils { secretKey = "datalookdatalook", iv = "NEWCAPECNEWCAPEC", }; var cipherText = sm4.Encrypt_CBC(plainText).ToUpper(); //plainText = sm4.Decrypt_CBC(cipherText); byte[]...

     

                SM4Utils sm4 = new SM4Utils { secretKey = "datalookdatalook", iv = "NEWCAPECNEWCAPEC", };
    
                var cipherText = sm4.Encrypt_CBC(plainText).ToUpper();
    
                //plainText = sm4.Decrypt_CBC(cipherText);
    
                byte[] md = new byte[32];
                byte[] msg1 = Encoding.Default.GetBytes(cipherText);
                SM3Digest sm3 = new SM3Digest();
                sm3.BlockUpdate(msg1, 0, msg1.Length);
                sm3.DoFinal(md, 0);
                var sign = new UTF8Encoding().GetString(Hex.Encode(md));
    
     
    

     

    public class Cipher {
            private int ct = 1;
    
    
            private ECPoint p2;
            private SM3Digest sm3keybase;
            private SM3Digest sm3c3;
    
    
            private byte[] key = new byte[32];
            private byte keyOff = 0;
    
    
            public Cipher() {
            }
    
    
            private void Reset() {
                sm3keybase = new SM3Digest();
                sm3c3 = new SM3Digest();
    
    
                byte[] p;
    
    
                p = p2.X.ToBigInteger().ToByteArray();
                sm3keybase.BlockUpdate(p, 0, p.Length);
                sm3c3.BlockUpdate(p, 0, p.Length);
    
    
                p = p2.Y.ToBigInteger().ToByteArray();
                sm3keybase.BlockUpdate(p, 0, p.Length);
    
    
                ct = 1;
                NextKey();
            }
    
    
            private void NextKey() {
                SM3Digest sm3keycur = new SM3Digest(sm3keybase);
                sm3keycur.Update((byte)(ct >> 24 & 0x00ff));
                sm3keycur.Update((byte)(ct >> 16 & 0x00ff));
                sm3keycur.Update((byte)(ct >> 8 & 0x00ff));
                sm3keycur.Update((byte)(ct & 0x00ff));
                sm3keycur.DoFinal(key, 0);
                keyOff = 0;
                ct++;
            }
    
    
            public virtual ECPoint Init_enc(SM2 sm2, ECPoint userKey) {
                BigInteger k = null;
                ECPoint c1 = null;
    
    
                AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.GenerateKeyPair();
                ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;
                ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;
                k = ecpriv.D;
                c1 = ecpub.Q;
    
    
                p2 = userKey.Multiply(k);
                Reset();
    
    
                return c1;
            }
    
    
            public virtual void Encrypt(byte[] data) {
                sm3c3.BlockUpdate(data, 0, data.Length);
                for (int i = 0; i < data.Length; i++) {
                    if (keyOff == key.Length)
                        NextKey();
    
    
                    data[i] ^= key[keyOff++];
                }
            }
    
    
            public virtual void Init_dec(BigInteger userD, ECPoint c1) {
                p2 = c1.Multiply(userD);
                Reset();
            }
    
    
            public virtual void Decrypt(byte[] data) {
                for (int i = 0; i < data.Length; i++) {
                    if (keyOff == key.Length)
                        NextKey();
    
    
                    data[i] ^= key[keyOff++];
                }
                sm3c3.BlockUpdate(data, 0, data.Length);
            }
    
    
            public virtual void Dofinal(byte[] c3) {
                byte[] p = p2.Y.ToBigInteger().ToByteArray();
                sm3c3.BlockUpdate(p, 0, p.Length);
                sm3c3.DoFinal(c3, 0);
                Reset();
            }
        }
        //https://blog.csdn.net/ErErFei/article/details/50999820
        public class SM2 {
            public static SM2 Instance {
                get {
                    return new SM2();
                }
    
            }
            public static SM2 InstanceTest {
                get {
                    return new SM2();
                }
    
            }
    
            public static readonly string[] sm2_param = {
                "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0
    			"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1
    			"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2
    			"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3
    			"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4
    			"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" // gy,5
    	    };
    
            public string[] ecc_param = sm2_param;
    
            public readonly BigInteger ecc_p;
            public readonly BigInteger ecc_a;
            public readonly BigInteger ecc_b;
            public readonly BigInteger ecc_n;
            public readonly BigInteger ecc_gx;
            public readonly BigInteger ecc_gy;
    
            public readonly ECCurve ecc_curve;
            public readonly ECPoint ecc_point_g;
    
            public readonly ECDomainParameters ecc_bc_spec;
    
            public readonly ECKeyPairGenerator ecc_key_pair_generator;
    
            private SM2() {
                ecc_param = sm2_param;
    
                ECFieldElement ecc_gx_fieldelement;
                ECFieldElement ecc_gy_fieldelement;
    
                ecc_p = new BigInteger(ecc_param[0], 16);
                ecc_a = new BigInteger(ecc_param[1], 16);
                ecc_b = new BigInteger(ecc_param[2], 16);
                ecc_n = new BigInteger(ecc_param[3], 16);
                ecc_gx = new BigInteger(ecc_param[4], 16);
                ecc_gy = new BigInteger(ecc_param[5], 16);
    
    
                ecc_gx_fieldelement = new FpFieldElement(ecc_p, ecc_gx);
                ecc_gy_fieldelement = new FpFieldElement(ecc_p, ecc_gy);
    
                ecc_curve = new FpCurve(ecc_p, ecc_a, ecc_b);
                ecc_point_g = new FpPoint(ecc_curve, ecc_gx_fieldelement, ecc_gy_fieldelement);
    
                ecc_bc_spec = new ECDomainParameters(ecc_curve, ecc_point_g, ecc_n);
    
                ECKeyGenerationParameters ecc_ecgenparam;
                ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom());
    
                ecc_key_pair_generator = new ECKeyPairGenerator();
                ecc_key_pair_generator.Init(ecc_ecgenparam);
            }
    
            public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey) {
                SM3Digest sm3 = new SM3Digest();
                byte[] p;
                // userId length
                int len = userId.Length * 8;
                sm3.Update((byte)(len >> 8 & 0x00ff));
                sm3.Update((byte)(len & 0x00ff));
    
                // userId
                sm3.BlockUpdate(userId, 0, userId.Length);
    
                // a,b
                p = ecc_a.ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
                p = ecc_b.ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
                // gx,gy
                p = ecc_gx.ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
                p = ecc_gy.ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
    
                // x,y
                p = userKey.X.ToBigInteger().ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
                p = userKey.Y.ToBigInteger().ToByteArray();
                sm3.BlockUpdate(p, 0, p.Length);
    
                // Z
                byte[] md = new byte[sm3.GetDigestSize()];
                sm3.DoFinal(md, 0);
    
                return md;
            }
    
        }
    class SM2Utils {
            public static void GenerateKeyPair() {
                SM2 sm2 = SM2.Instance;
                AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.GenerateKeyPair();
                ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;
                ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;
                BigInteger privateKey = ecpriv.D;
                ECPoint publicKey = ecpub.Q;
    
                System.Console.Out.WriteLine("公钥: " + Encoding.UTF8.GetString(Hex.Encode(publicKey.GetEncoded())).ToUpper());
                System.Console.Out.WriteLine("私钥: " + Encoding.UTF8.GetString(Hex.Encode(privateKey.ToByteArray())).ToUpper());
            }
    
            public static String Encrypt(byte[] publicKey, byte[] data) {
                if (null == publicKey || publicKey.Length == 0) {
                    return null;
                }
                if (data == null || data.Length == 0) {
                    return null;
                }
    
                byte[] source = new byte[data.Length];
                Array.Copy(data, 0, source, 0, data.Length);
    
                Cipher cipher = new Cipher();
                SM2 sm2 = SM2.Instance;
    
                ECPoint userKey = sm2.ecc_curve.DecodePoint(publicKey);
    
                ECPoint c1 = cipher.Init_enc(sm2, userKey);
                cipher.Encrypt(source);
    
                byte[] c3 = new byte[32];
                cipher.Dofinal(c3);
    
                String sc1 = Encoding.UTF8.GetString(Hex.Encode(c1.GetEncoded()));
                String sc2 = Encoding.UTF8.GetString(Hex.Encode(source));
                String sc3 = Encoding.UTF8.GetString(Hex.Encode(c3));
    
                return (sc1 + sc2 + sc3).ToUpper();
            }
    
            public static byte[] Decrypt(byte[] privateKey, byte[] encryptedData) {
                if (null == privateKey || privateKey.Length == 0) {
                    return null;
                }
                if (encryptedData == null || encryptedData.Length == 0) {
                    return null;
                }
    
                String data = Encoding.UTF8.GetString(Hex.Encode(encryptedData));
    
                byte[] c1Bytes = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(0, 130)));
                int c2Len = encryptedData.Length - 97;
                byte[] c2 = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(130, 2 * c2Len)));
                byte[] c3 = Hex.Decode(Encoding.UTF8.GetBytes(data.Substring(130 + 2 * c2Len, 64)));
    
                SM2 sm2 = SM2.Instance;
                BigInteger userD = new BigInteger(1, privateKey);
    
                ECPoint c1 = sm2.ecc_curve.DecodePoint(c1Bytes);
                Cipher cipher = new Cipher();
                cipher.Init_dec(userD, c1);
                cipher.Decrypt(c2);
                cipher.Dofinal(c3);
    
                return c2;
            }
    
            public static void test() {
    
                //GenerateKeyPair();
    
                //var cipherText = "042BE5CF9B720C88E3DC88058C6CCD243F9FD504C23EC27C774F787A53D42E2074DBD3A744C62FD484B9853A8705AE1F554FC65E6B7373AF33304037971B33F2108D07610D7EDF0B4FC7FC0480959CCD864F9D253A57587229A8B2E518E1FA5F837B3DEDD339A7BFEB1A57362E7D626D919";
                //044D206F9A8AC5D0E7FB636A4C34D5D3FCA729FFCD8A020AF79134AB69802AB7D96633EAC57DB0A5DFC73FB416116AE519D627E6D6688CB21D8E92BBFF0749CB6D03C437E0E90658CBF04A517A493F1765F202DAF2DA3C7FA7348F2B09DDC15E8A1041029AB7EC12E2E324383DEBF87E97
    
                //String plainText = "1000000722200600";
    
                String plainText = "zhumz";
                byte[] sourceData = Encoding.UTF8.GetBytes(plainText);
    
                //下面的秘钥可以使用generateKeyPair()生成的秘钥内容  
                // 国密规范正式私钥  
                String prik = "5725E6C4EB6100881F76F6D82766911B5F0096FF9D47EE39BF4278AF8B63ED49";
                // 国密规范正式公钥  
                String pubk = "045212E1AD028AC8A5C2CA1884AF2AEACABC81417728102B281D0B8E518C8C86ECC738604B694D1F697B3754C017CF8604047F67B4EBF7DC9C58BC7809C4DA2349";
    
                System.Console.Out.WriteLine("加密: ");
                String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);
                System.Console.Out.WriteLine(cipherText);
    
    
                System.Console.Out.WriteLine("解密: ");
                plainText = Encoding.UTF8.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));
                System.Console.Out.WriteLine(plainText);
    
                Console.ReadLine();
    
            }
    
            //[STAThread]
            //public static void Main()
            //{
            //    GenerateKeyPair();
    
            //    String plainText = "ererfeiisgod";
            //    byte[] sourceData = Encoding.UTF8.GetBytes(plainText);
    
            //    //下面的秘钥可以使用generateKeyPair()生成的秘钥内容  
            //    // 国密规范正式私钥  
            //    String prik = "3690655E33D5EA3D9A4AE1A1ADD766FDEA045CDEAA43A9206FB8C430CEFE0D94";
            //    // 国密规范正式公钥  
            //    String pubk = "04F6E0C3345AE42B51E06BF50B98834988D54EBC7460FE135A48171BC0629EAE205EEDE253A530608178A98F1E19BB737302813BA39ED3FA3C51639D7A20C7391A";
    
            //    System.Console.Out.WriteLine("加密: ");
            //    String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);
            //    System.Console.Out.WriteLine(cipherText);
            //    System.Console.Out.WriteLine("解密: ");
            //    plainText = Encoding.UTF8.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));
            //    System.Console.Out.WriteLine(plainText);
    
            //    Console.ReadLine();
            //}
        }
        public abstract class GeneralDigest : IDigest {
            private const int BYTE_LENGTH = 64;
    
            private byte[] xBuf;
            private int xBufOff;
    
            private long byteCount;
    
            internal GeneralDigest() {
                xBuf = new byte[4];
            }
    
            internal GeneralDigest(GeneralDigest t) {
                xBuf = new byte[t.xBuf.Length];
                Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
    
                xBufOff = t.xBufOff;
                byteCount = t.byteCount;
            }
    
            public void Update(byte input) {
                xBuf[xBufOff++] = input;
    
                if (xBufOff == xBuf.Length) {
                    ProcessWord(xBuf, 0);
                    xBufOff = 0;
                }
    
                byteCount++;
            }
    
            public void BlockUpdate(
                byte[] input,
                int inOff,
                int length) {
                //
                // fill the current word
                //
                while ((xBufOff != 0) && (length > 0)) {
                    Update(input[inOff]);
                    inOff++;
                    length--;
                }
    
                //
                // process whole words.
                //
                while (length > xBuf.Length) {
                    ProcessWord(input, inOff);
    
                    inOff += xBuf.Length;
                    length -= xBuf.Length;
                    byteCount += xBuf.Length;
                }
    
                //
                // load in the remainder.
                //
                while (length > 0) {
                    Update(input[inOff]);
    
                    inOff++;
                    length--;
                }
            }
    
            public void Finish() {
                long bitLength = (byteCount << 3);
    
                //
                // add the pad bytes.
                //
                Update(unchecked((byte)128));
    
                while (xBufOff != 0) Update(unchecked((byte)0));
                ProcessLength(bitLength);
                ProcessBlock();
            }
    
            public virtual void Reset() {
                byteCount = 0;
                xBufOff = 0;
                Array.Clear(xBuf, 0, xBuf.Length);
            }
    
            public int GetByteLength() {
                return BYTE_LENGTH;
            }
    
            internal abstract void ProcessWord(byte[] input, int inOff);
            internal abstract void ProcessLength(long bitLength);
            internal abstract void ProcessBlock();
            public abstract string AlgorithmName { get; }
            public abstract int GetDigestSize();
            public abstract int DoFinal(byte[] output, int outOff);
        }
    
        public class SupportClass {
            /// <summary>
            /// Performs an unsigned bitwise right shift with the specified number
            /// </summary>
            /// <param name="number">Number to operate on</param>
            /// <param name="bits">Ammount of bits to shift</param>
            /// <returns>The resulting number from the shift operation</returns>
            public static int URShift(int number, int bits) {
                if (number >= 0)
                    return number >> bits;
                else
                    return (number >> bits) + (2 << ~bits);
            }
    
            /// <summary>
            /// Performs an unsigned bitwise right shift with the specified number
            /// </summary>
            /// <param name="number">Number to operate on</param>
            /// <param name="bits">Ammount of bits to shift</param>
            /// <returns>The resulting number from the shift operation</returns>
            public static int URShift(int number, long bits) {
                return URShift(number, (int)bits);
            }
    
            /// <summary>
            /// Performs an unsigned bitwise right shift with the specified number
            /// </summary>
            /// <param name="number">Number to operate on</param>
            /// <param name="bits">Ammount of bits to shift</param>
            /// <returns>The resulting number from the shift operation</returns>
            public static long URShift(long number, int bits) {
                if (number >= 0)
                    return number >> bits;
                else
                    return (number >> bits) + (2L << ~bits);
            }
    
            /// <summary>
            /// Performs an unsigned bitwise right shift with the specified number
            /// </summary>
            /// <param name="number">Number to operate on</param>
            /// <param name="bits">Ammount of bits to shift</param>
            /// <returns>The resulting number from the shift operation</returns>
            public static long URShift(long number, long bits) {
                return URShift(number, (int)bits);
            }
    
    
        }
    
        public class SM3Digest : GeneralDigest {
            public override string AlgorithmName {
                get {
                    return "SM3";
                }
    
            }
            public override int GetDigestSize() {
                return DIGEST_LENGTH;
            }
    
            private const int DIGEST_LENGTH = 32;
    
            private static readonly int[] v0 = new int[] { 0x7380166f, 0x4914b2b9, 0x172442d7, unchecked((int)0xda8a0600), unchecked((int)0xa96f30bc), 0x163138aa, unchecked((int)0xe38dee4d), unchecked((int)0xb0fb0e4e) };
    
            private int[] v = new int[8];
            private int[] v_ = new int[8];
    
            private static readonly int[] X0 = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
            private int[] X = new int[68];
            private int xOff;
    
            private int T_00_15 = 0x79cc4519;
            private int T_16_63 = 0x7a879d8a;
    
            public SM3Digest() {
                Reset();
            }
    
            public SM3Digest(SM3Digest t) : base(t) {
    
                Array.Copy(t.X, 0, X, 0, t.X.Length);
                xOff = t.xOff;
    
                Array.Copy(t.v, 0, v, 0, t.v.Length);
            }
    
            public override void Reset() {
                base.Reset();
    
                Array.Copy(v0, 0, v, 0, v0.Length);
    
                xOff = 0;
                Array.Copy(X0, 0, X, 0, X0.Length);
            }
    
            internal override void ProcessBlock() {
                int i;
    
                int[] ww = X;
                int[] ww_ = new int[64];
    
                for (i = 16; i < 68; i++) {
                    ww[i] = P1(ww[i - 16] ^ ww[i - 9] ^ (ROTATE(ww[i - 3], 15))) ^ (ROTATE(ww[i - 13], 7)) ^ ww[i - 6];
                }
    
                for (i = 0; i < 64; i++) {
                    ww_[i] = ww[i] ^ ww[i + 4];
                }
    
                int[] vv = v;
                int[] vv_ = v_;
    
                Array.Copy(vv, 0, vv_, 0, v0.Length);
    
                int SS1, SS2, TT1, TT2, aaa;
                for (i = 0; i < 16; i++) {
                    aaa = ROTATE(vv_[0], 12);
                    SS1 = aaa + vv_[4] + ROTATE(T_00_15, i);
                    SS1 = ROTATE(SS1, 7);
                    SS2 = SS1 ^ aaa;
    
                    TT1 = FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 + ww_[i];
                    TT2 = GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 + ww[i];
                    vv_[3] = vv_[2];
                    vv_[2] = ROTATE(vv_[1], 9);
                    vv_[1] = vv_[0];
                    vv_[0] = TT1;
                    vv_[7] = vv_[6];
                    vv_[6] = ROTATE(vv_[5], 19);
                    vv_[5] = vv_[4];
                    vv_[4] = P0(TT2);
                }
                for (i = 16; i < 64; i++) {
                    aaa = ROTATE(vv_[0], 12);
                    SS1 = aaa + vv_[4] + ROTATE(T_16_63, i);
                    SS1 = ROTATE(SS1, 7);
                    SS2 = SS1 ^ aaa;
    
                    TT1 = FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3] + SS2 + ww_[i];
                    TT2 = GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7] + SS1 + ww[i];
                    vv_[3] = vv_[2];
                    vv_[2] = ROTATE(vv_[1], 9);
                    vv_[1] = vv_[0];
                    vv_[0] = TT1;
                    vv_[7] = vv_[6];
                    vv_[6] = ROTATE(vv_[5], 19);
                    vv_[5] = vv_[4];
                    vv_[4] = P0(TT2);
                }
                for (i = 0; i < 8; i++) {
                    vv[i] ^= vv_[i];
                }
    
                // Reset
                xOff = 0;
                Array.Copy(X0, 0, X, 0, X0.Length);
            }
    
            internal override void ProcessWord(byte[] in_Renamed, int inOff) {
                int n = in_Renamed[inOff] << 24;
                n |= (in_Renamed[++inOff] & 0xff) << 16;
                n |= (in_Renamed[++inOff] & 0xff) << 8;
                n |= (in_Renamed[++inOff] & 0xff);
                X[xOff] = n;
    
                if (++xOff == 16) {
                    ProcessBlock();
                }
            }
    
            internal override void ProcessLength(long bitLength) {
                if (xOff > 14) {
                    ProcessBlock();
                }
    
                X[14] = (int)(SupportClass.URShift(bitLength, 32));
                X[15] = (int)(bitLength & unchecked((int)0xffffffff));
            }
    
            public static void IntToBigEndian(int n, byte[] bs, int off) {
                bs[off] = (byte)(SupportClass.URShift(n, 24));
                bs[++off] = (byte)(SupportClass.URShift(n, 16));
                bs[++off] = (byte)(SupportClass.URShift(n, 8));
                bs[++off] = (byte)(n);
            }
    
            public override int DoFinal(byte[] out_Renamed, int outOff) {
                Finish();
    
                for (int i = 0; i < 8; i++) {
                    IntToBigEndian(v[i], out_Renamed, outOff + i * 4);
                }
    
                Reset();
    
                return DIGEST_LENGTH;
            }
    
            private int ROTATE(int x, int n) {
                return (x << n) | (SupportClass.URShift(x, (32 - n)));
            }
    
            private int P0(int X) {
                return ((X) ^ ROTATE((X), 9) ^ ROTATE((X), 17));
            }
    
            private int P1(int X) {
                return ((X) ^ ROTATE((X), 15) ^ ROTATE((X), 23));
            }
    
            private int FF_00_15(int X, int Y, int Z) {
                return (X ^ Y ^ Z);
            }
    
            private int FF_16_63(int X, int Y, int Z) {
                return ((X & Y) | (X & Z) | (Y & Z));
            }
    
            private int GG_00_15(int X, int Y, int Z) {
                return (X ^ Y ^ Z);
            }
    
            private int GG_16_63(int X, int Y, int Z) {
                return ((X & Y) | (~X & Z));
            }
    
            //[STAThread]
            //public static void  Main()
            //{
            //    byte[] md = new byte[32];
            //    byte[] msg1 = Encoding.Default.GetBytes("ererfeiisgod");
            //    SM3Digest sm3 = new SM3Digest();
            //    sm3.BlockUpdate(msg1, 0, msg1.Length);
            //    sm3.DoFinal(md, 0);
            //    System.String s = new UTF8Encoding().GetString(Hex.Encode(md));
            //    System.Console.Out.WriteLine(s.ToUpper());
    
            //    Console.ReadLine();
            //}
        }
     public class SM4 {
            public const int SM4_ENCRYPT = 1;
            public const int SM4_DECRYPT = 0;
            private long GET_ULONG_BE(byte[] b, int i) {
                long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL;
                return n;
            }
    
            private void PUT_ULONG_BE(long 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 long SHL(long x, int n) {
                return (x & 0xFFFFFFFF) << n;
            }
    
            private long ROTL(long x, int n) {
                return SHL(x, n) | x >> (32 - n);
            }
    
            private void SWAP(long[] sk, int i) {
                long t = sk[i];
                sk[i] = sk[(31 - i)];
                sk[(31 - i)] = t;
            }
    
            public byte[] SboxTable = new byte[] { (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 uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
    
            public uint[] 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 long sm4Lt(long ka) {
                long bb = 0L;
                long c = 0L;
                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 long sm4F(long x0, long x1, long x2, long x3, long rk) {
                return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);
            }
    
            private long sm4CalciRK(long ka) {
                long bb = 0L;
                long rk = 0L;
                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(long[] SK, byte[] key) {
                long[] MK = new long[4];
                long[] k = new long[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] ^ (long)FK[0];
                k[1] = MK[1] ^ (long)FK[1];
                k[2] = MK[2] ^ (long)FK[2];
                k[3] = MK[3] ^ (long)FK[3];
                for (; i < 32; i++) {
                    k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i]));
                    SK[i] = k[(i + 4)];
                }
            }
    
            private void sm4_one_round(long[] sk, byte[] input, byte[] output) {
                int i = 0;
                long[] ulbuf = new long[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];
                    Array.Copy(input, 0, ret, 0, input.Length);
                    for (int i = 0; i < p; i++) {
                        ret[input.Length + i] = (byte)p;
                    }
                    return ret;
                } else {
                    int p = input[input.Length - 1];
                    if (input.Length <= p) {
                        byte[] temp = null;
                        return temp;
                    } else {
                        ret = new byte[input.Length - p];
                        Array.Copy(input, 0, ret, 0, input.Length - p);
                        return ret;
                    }
                }
                //return ret;
            }
    
            public void sm4_setkey_enc(SM4_Context ctx, byte[] key) {
                ctx.mode = SM4_ENCRYPT;
                sm4_setkey(ctx.sk, key);
            }
    
            public void sm4_setkey_dec(SM4_Context ctx, byte[] key) {
                int i = 0;
                ctx.mode = SM4_DECRYPT;
                sm4_setkey(ctx.sk, key);
                for (i = 0; i < 16; i++) {
                    SWAP(ctx.sk, i);
                }
            }
    
            public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) {
                if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) {
                    byte[] temp = padding(input, SM4_ENCRYPT);
                    if (temp == null) {
                        return temp;
                    } else {
                        input = padding(input, SM4_ENCRYPT);
                    }
                }
    
                int length = input.Length;
                byte[] bins = new byte[length];
                Array.Copy(input, 0, bins, 0, length);
                byte[] bous = new byte[length];
                for (int i = 0; length > 0; length -= 16, i++) {
                    byte[] inBytes = new byte[16];
                    byte[] outBytes = new byte[16];
                    Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
                    sm4_one_round(ctx.sk, inBytes, outBytes);
                    Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length);
                }
    
                if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
                    byte[] temp = padding(bous, SM4_DECRYPT);
                    if (temp == null) {
                        return temp;
                    } else {
                        bous = padding(bous, SM4_DECRYPT);
                        return bous;
                    }
                } else {
                    return bous;
                }
            }
    
            public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) {
                if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) {
                    byte[] temp = padding(input, SM4_ENCRYPT);
                    if (temp == null) {
                        return temp;
                    } else {
                        input = padding(input, SM4_ENCRYPT);
                    }
                }
    
                int i = 0;
                int length = input.Length;
                byte[] bins = new byte[length];
                Array.Copy(input, 0, bins, 0, length);
                byte[] bous = null;
                List<byte> bousList = new List<byte>();
                if (ctx.mode == SM4_ENCRYPT) {
                    for (int j = 0; length > 0; length -= 16, j++) {
                        byte[] inBytes = new byte[16];
                        byte[] outBytes = new byte[16];
                        byte[] out1 = new byte[16];
    
                        Array.Copy(bins, j * 16, inBytes, 0, length > 16 ? 16 : length);//原代码有错,需将i * 16改为j * 16
                        for (i = 0; i < 16; i++) {
                            outBytes[i] = ((byte)(inBytes[i] ^ iv[i]));
                        }
                        sm4_one_round(ctx.sk, outBytes, out1);
                        Array.Copy(out1, 0, iv, 0, 16);
                        for (int k = 0; k < 16; k++) {
                            bousList.Add(out1[k]);
                        }
                    }
                } else {
                    byte[] temp = new byte[16];
                    for (int j = 0; length > 0; length -= 16, j++) {
                        byte[] inBytes = new byte[16];
                        byte[] outBytes = new byte[16];
                        byte[] out1 = new byte[16];
    
                        Array.Copy(bins, j * 16, inBytes, 0, length > 16 ? 16 : length);//原代码有错,需将i * 16改为j * 16
                        Array.Copy(inBytes, 0, temp, 0, 16);
                        sm4_one_round(ctx.sk, inBytes, outBytes);
                        for (i = 0; i < 16; i++) {
                            out1[i] = ((byte)(outBytes[i] ^ iv[i]));
                        }
                        Array.Copy(temp, 0, iv, 0, 16);
                        for (int k = 0; k < 16; k++) {
                            bousList.Add(out1[k]);
                        }
                    }
    
                }
    
                if (ctx.isPadding && ctx.mode == SM4_DECRYPT) {
                    byte[] temp = padding(bousList.ToArray(), SM4_DECRYPT);
                    if (temp == null) {
                        return temp;
                    } else {
                        bous = padding(bousList.ToArray(), SM4_DECRYPT);
                        return bous;
                    }
                } else {
                    return bousList.ToArray();
                }
            }
        }
        public class SM4_Context {
            public int mode;
    
            public long[] sk;
    
            public bool isPadding;
    
            public SM4_Context() {
                this.mode = 1;
                this.isPadding = true;
                this.sk = new long[32];
            }
        }
    public class SM4Utils {
            public string secretKey = "";
            public string iv = "";
            public bool hexString = false;
            public byte[] secretKeyBuff;
    
            public string Encrypt_ECB(string plainData) {
                SM4_Context ctx = new SM4_Context();
                ctx.isPadding = true;
                ctx.mode = SM4.SM4_ENCRYPT;
    
                byte[] keyBytes;
                if (hexString) {
                    keyBytes = Decode(secretKey);
                } else {
                    keyBytes = Encoding.UTF8.GetBytes(secretKey);
                }
    
                SM4 sm4 = new SM4();
                sm4.sm4_setkey_enc(ctx, keyBytes);
                byte[] encrypted = sm4.sm4_crypt_ecb(ctx, Encoding.UTF8.GetBytes(plainData));
                //return encrypted;
                string cipherText = Encoding.UTF8.GetString(Encode(encrypted));
                return cipherText;
            }
    
            public string Decrypt_ECB(string cipherText) {
                SM4_Context ctx = new SM4_Context();
                ctx.isPadding = true;
                ctx.mode = SM4.SM4_DECRYPT;
    
                byte[] keyBytes;
                if (hexString) {
                    keyBytes = Decode(secretKey);
                } else {
                    keyBytes = Encoding.UTF8.GetBytes(secretKey);
                }
    
                SM4 sm4 = new SM4();
                sm4.sm4_setkey_dec(ctx, keyBytes);
                byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Decode(cipherText));
                if (decrypted == null) {
                    return string.Empty;
                } else {
                    return Encoding.UTF8.GetString(decrypted);
                }
            }
    
            public string Encrypt_CBC(string plainData) {
                SM4_Context ctx = new SM4_Context();
                ctx.isPadding = true;
                ctx.mode = SM4.SM4_ENCRYPT;
    
                byte[] keyBytes;
                byte[] ivBytes;
                if (hexString) {
                    keyBytes = Decode(secretKey);
                    ivBytes = Decode(iv);
                } else {
                    keyBytes = Encoding.UTF8.GetBytes(secretKey);
                    ivBytes = Encoding.UTF8.GetBytes(iv);
                }
    
                SM4 sm4 = new SM4();
                sm4.sm4_setkey_enc(ctx, keyBytes);
                byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.UTF8.GetBytes(plainData));
    
                //return Hex.Encode(encrypted);
                //return encrypted;
                string cipherText = Encoding.UTF8.GetString(Encode(encrypted));
                return cipherText;
            }
    
            public string Decrypt_CBC(string cipherData) {
                SM4_Context ctx = new SM4_Context();
                ctx.isPadding = true;
                ctx.mode = SM4.SM4_DECRYPT;
    
                byte[] keyBytes;
                byte[] ivBytes;
                if (hexString) {
                    keyBytes = Decode(secretKey);
                    ivBytes = Decode(iv);
                } else {
                    keyBytes = Encoding.UTF8.GetBytes(secretKey);
                    ivBytes = Encoding.UTF8.GetBytes(iv);
                }
    
                SM4 sm4 = new SM4();
                sm4.sm4_setkey_dec(ctx, keyBytes);
                byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Decode(cipherData));
                if (decrypted == null) {
                    return string.Empty;
                } else {
                    return Encoding.UTF8.GetString(decrypted);
                }
                //return decrypted;
            }
    
    
            public byte[] Encode(byte[] data) {
                int off = 0;
                int length = data.Length;
    
                MemoryStream memoryStream = new MemoryStream(length * 2);
    
                for (int index = off; index < off + length; ++index) {
                    int num = (int)data[index];
                    memoryStream.WriteByte(this.encodingTable[num >> 4]);
                    memoryStream.WriteByte(this.encodingTable[num & 15]);
                }
                length = length * 2;
    
                return memoryStream.ToArray();
            }
    
    
    
    
            public byte[] Decode(string data) {
                MemoryStream memoryStream = new MemoryStream((data.Length + 1) / 2);
    
    
                int num1 = 0;
                int length = data.Length;
                while (length > 0 && Ignore(data[length - 1]))
                    --length;
                int index1 = 0;
                InitialiseDecodingTable();
                while (index1 < length) {
                    while (index1 < length && Ignore(data[index1]))
                        ++index1;
                    byte[] decodingTable1 = this.decodingTable;
                    string str1 = data;
                    int index2 = index1;
                    int index3 = index2 + 1;
                    int index4 = (int)str1[index2];
                    byte num2 = decodingTable1[index4];
                    while (index3 < length && Ignore(data[index3]))
                        ++index3;
                    byte[] decodingTable2 = this.decodingTable;
                    string str2 = data;
                    int index5 = index3;
                    index1 = index5 + 1;
                    int index6 = (int)str2[index5];
                    byte num3 = decodingTable2[index6];
                    if (((int)num2 | (int)num3) >= 128)
                        throw new IOException("invalid characters encountered in Hex data");
                    memoryStream.WriteByte((byte)((uint)num2 << 4 | (uint)num3));
                    ++num1;
                }
                // return num1;
                byte[] rst = memoryStream.ToArray();
                return memoryStream.ToArray();
            }
    
    
    
    
            public byte[] Decode(byte[] data) {
                int off = 0;
                int length = data.Length;
                MemoryStream memoryStream = new MemoryStream(length * 2);
    
                for (int index = off; index < off + length; ++index) {
                    int num = (int)data[index];
                    memoryStream.WriteByte(this.encodingTable[num >> 4]);
                    memoryStream.WriteByte(this.encodingTable[num & 15]);
                }
                length = length * 2;
    
                return memoryStream.ToArray();
    
            }
    
            protected byte[] decodingTable = new byte[128];
    
    
            public static void Fill(byte[] buf, byte b) {
                int length = buf.Length;
                while (length > 0)
                    buf[--length] = b;
            }
            protected void InitialiseDecodingTable() {
                //Arrays.Fill(this.decodingTable, byte.MaxValue);
    
                int length = this.decodingTable.Length;
                while (length > 0) {
                    this.decodingTable[--length] = byte.MaxValue;
                }
    
    
                for (int index = 0; index < this.encodingTable.Length; ++index)
                    this.decodingTable[(int)this.encodingTable[index]] = (byte)index;
                this.decodingTable[65] = this.decodingTable[97];
                this.decodingTable[66] = this.decodingTable[98];
                this.decodingTable[67] = this.decodingTable[99];
                this.decodingTable[68] = this.decodingTable[100];
                this.decodingTable[69] = this.decodingTable[101];
                this.decodingTable[70] = this.decodingTable[102];
            }
    
            protected byte[] encodingTable =
            {
                (byte) 48,
                (byte) 49,
                (byte) 50,
                (byte) 51,
                (byte) 52,
                (byte) 53,
                (byte) 54,
                (byte) 55,
                (byte) 56,
                (byte) 57,
                (byte) 97,
                (byte) 98,
                (byte) 99,
                (byte) 100,
                (byte) 101,
                (byte) 102
            };
    
            private static bool ignore(char c) {
                return c == '\n' || c == '\r' || c == '\t' || c == ' ';
            }
    
            private static bool Ignore(char c) {
                if (c != '\n' && c != '\r' && c != '\t')
                    return c == ' ';
                return true;
            }
        }

    展开全文
  • 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==="obje...

    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

    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

    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

    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

    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;ud?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

    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

    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*|\t|\r|\n)/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*|\t|\r|\n)/g, "");

    }

    return cipherText;

    }

    catch ( e)

    {

    console.error(e);

    return null;

    }

    }

    stringToByte=function(str) {

    var bytes = new Array();

    var len, c;

    len = str.length;

    for(var i = 0; i < len; i++) {

    c = str.charCodeAt(i);

    if(c >= 0x010000 && c <= 0x10FFFF) {

    bytes.push(((c >> 18) & 0x07) | 0xF0);

    bytes.push(((c >> 12) & 0x3F) | 0x80);

    bytes.push(((c >> 6) & 0x3F) | 0x80);

    bytes.push((c & 0x3F) | 0x80);

    } else if(c >= 0x000800 && c <= 0x00FFFF) {

    bytes.push(((c >> 12) & 0x0F) | 0xE0);

    bytes.push(((c >> 6) & 0x3F) | 0x80);

    bytes.push((c & 0x3F) | 0x80);

    } else if(c >= 0x000080 && c <= 0x0007FF) {

    bytes.push(((c >> 6) & 0x1F) | 0xC0);

    bytes.push((c & 0x3F) | 0x80);

    } else {

    bytes.push(c & 0xFF);

    }

    }

    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*|\t|\r|\n");

    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*|\t|\r|\n");

    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);

    }

    }

    展开全文
  • sm4加密

    千次阅读 2021-01-13 00:40:58
    前言项目里需要用到sm4加密,在这里记录一下(springboot)。依赖bouncycastleorg.bouncycastlebcmail-jdk15on1.66cn.hutoolhutool-all5.4.1代码直接贴代码,可以根据自己的需要封装相对应的代码逻辑。//需要注意的是...

    前言

    项目里需要用到sm4加密,在这里记录一下(springboot)。

    依赖

    bouncycastle

    org.bouncycastle

    bcmail-jdk15on

    1.66

    cn.hutool

    hutool-all

    5.4.1

    代码

    直接贴代码,可以根据自己的需要封装相对应的代码逻辑。

    //需要注意的是,使用KeyGenerator生成密钥种子的时候,windows和linux上会产生不一致。

    //例如:

    KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, PROVIDER_NAME);

    SecureRandom random = new SecureRandom();

    if(null != seed && !"".equals(seed)){

    random.setSeed(seed.getBytes());

    }

    kg.init(keySize, random);

    //解决办法

    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

    import cn.hutool.core.util.HexUtil;

    import com.spinfo.common.constants.UserConstants;

    import com.spinfo.controller.UserController;

    import org.bouncycastle.jce.provider.BouncyCastleProvider;

    import org.bouncycastle.util.encoders.Base64;

    import org.slf4j.Logger;

    import org.slf4j.LoggerFactory;

    import org.springframework.util.DigestUtils;

    import javax.crypto.*;

    import javax.crypto.spec.IvParameterSpec;

    import javax.crypto.spec.SecretKeySpec;

    import java.security.*;

    import java.util.Arrays;

    public class SM4Util {

    private static Logger logger = LoggerFactory.getLogger(SM4Util.class);

    private static final String PROVIDER_NAME = "BC";

    public static final String ALGORITHM_NAME = "SM4";

    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";

    public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";

    public static final String DEFAULT_KEY = "random_seed";

    public static final int DEFAULT_KEY_SIZE = 128;

    private static final int ENCRYPT_MODE = 1;

    private static final int DECRYPT_MODE = 2;

    static {

    Security.addProvider(new BouncyCastleProvider());

    }

    public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {

    return generateKey(DEFAULT_KEY, DEFAULT_KEY_SIZE);

    }

    public static byte[] generateKey(String seed) throws NoSuchAlgorithmException, NoSuchProviderException {

    return generateKey(seed, DEFAULT_KEY_SIZE);

    }

    public static byte[] generateKey(String seed, int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {

    KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, PROVIDER_NAME);

    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

    if(null != seed && !"".equals(seed)){

    random.setSeed(seed.getBytes());

    }

    kg.init(keySize, random);

    return kg.generateKey().getEncoded();

    }

    /**

    * ecb 加密

    * @param key

    * @param data

    */

    public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {

    Cipher cipher = generateEcbCipher(ENCRYPT_MODE, key);

    return cipher.doFinal(data);

    }

    /**

    * ecb 解密

    * @param key

    * @param cipherText

    */

    public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {

    Cipher cipher = generateEcbCipher(DECRYPT_MODE, key);

    return cipher.doFinal(cipherText);

    }

    /**

    * cbc 加密

    * @param key

    * @param data

    */

    public static byte[] encryptCbcPadding(byte[] key, byte[] iv, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {

    Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);

    return cipher.doFinal(data);

    }

    public static String encryptCbcPaddingString(byte[] key, byte[] iv, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {

    Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);

    byte[] result = cipher.doFinal(data);

    return Base64.toBase64String(result);

    }

    /**

    * cbc 解密

    * @param key

    * @param iv

    * @param cipherText

    */

    public static byte[] decryptCbcPadding(byte[] key, byte[] iv, String cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException {

    byte[] cipherBytes = Base64.decode(cipherText);

    Cipher cipher = generateCbcCipher(DECRYPT_MODE, key, iv);

    return cipher.doFinal(cipherBytes);

    }

    public static byte[] decryptCbcPadding(byte[] key, byte[] iv, byte[] cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException {

    Cipher cipher = generateCbcCipher(DECRYPT_MODE, key, iv);

    return cipher.doFinal(cipherText);

    }

    /**

    * ecb cipher

    * @param mode

    * @param key

    * @return

    */

    private static Cipher generateEcbCipher(int mode, byte[] key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException {

    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, PROVIDER_NAME);

    Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);

    cipher.init(mode, sm4Key);

    return cipher;

    }

    /**

    * cbc cipher

    * @param mode

    * @param key

    * @return

    */

    private static Cipher generateCbcCipher(int mode, byte[] key, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {

    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, PROVIDER_NAME);

    Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);

    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

    cipher.init(mode, sm4Key, ivParameterSpec);

    return cipher;

    }

    /**

    * ecb 加密 times 次

    * @param data

    * @param salt

    * @param times

    * @return=

    */

    public static String encryptEcbDataTimes(String data, String salt, int times) throws GeneralSecurityException {

    try {

    byte[] key = HexUtil.decodeHex(salt);

    byte[] bytes = data.getBytes();

    for(int i = 0; i < times; ++i) {

    bytes = encryptEcbPadding(key, bytes);

    }

    data = Base64.toBase64String(bytes);

    return data;

    } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {

    throw new GeneralSecurityException("SM4加密失败");

    }

    }

    /**

    * ecb 解密 times 次

    * @param data

    * @param salt

    * @param times

    * @return

    * @throws GeneralSecurityException

    */

    public static String decryptEcbDataTimes(String data, String salt, int times) throws GeneralSecurityException {

    try {

    byte[] bytes = Base64.decode(data);

    byte[] key = HexUtil.decodeHex(salt);

    for(int i = 0; i < times; ++i) {

    bytes = decryptEcbPadding(key, bytes);

    }

    data = new String(bytes);

    return data;

    } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {

    throw new GeneralSecurityException("SM4解密失败");

    }

    }

    /**

    * cbc 加密 times 次

    * @param data

    * @param salt

    * @param times

    * @return=

    */

    public static String encryptCbcDataTimes(String data, String salt, int times) {

    try {

    byte[] iv = generateKey();

    byte[] key = generateKey(salt);

    byte[] bytes = data.getBytes();

    Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);

    for(int i = 0; i < times; ++i) {

    bytes = cipher.doFinal(bytes);

    }

    data = Base64.toBase64String(bytes);

    return data;

    } catch (Exception e) {

    e.printStackTrace();

    return null;

    }

    }

    /**

    * cbc 解密 times 次

    * @param data

    * @param salt

    * @param times

    * @return

    * @throws GeneralSecurityException

    */

    public static String decryptCbcDataTimes(String data, String salt, int times) throws GeneralSecurityException {

    try {

    byte[] iv = generateKey();

    byte[] bytes = Base64.decode(data);

    byte[] key = generateKey(salt);

    Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);

    for(int i = 0; i < times; ++i) {

    bytes = cipher.doFinal(bytes);

    }

    data = new String(bytes);

    return data;

    } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {

    throw new GeneralSecurityException("SM4解密失败");

    }

    }

    }

    展开全文
  • https://www.cnblogs.com/miaoziblog/p/9040473.html近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多数据类型与C#的...

    https://www.cnblogs.com/miaoziblog/p/9040473.html

    近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多数据类型与C#的相同的数据类型是存在不同的比如:byte在Java中范围是-127~128,而C#中的范围是0~255,这就导致使用C#的加密的明文产生的密文到Java中解密不正确。再一次偶尔的上网中看到了这篇文章 https://www.cnblogs.com/wyongbo/p/jnaTest.html,个人做了个例子果然可以,哎哎哎发现了新大陆,哈哈哈哈^_^,然后就按照这个思路,既然C#和Java之间不能相互加密解密,那就让他们使用同一个语言进行加密解密,就是加密和解密都是用C#就可以完美的解决了。

    C#SM4加密代码

    下面详细解释各个类。首先以管理员打开VS(我使用的是VS2015),首先要下载一个dll包——BouncyCastle.Crypto.dll,并将此dll引用到项目中

    0f691c9b2c5156fbf0a7560d8e7971ae.png

    Sm4类代码如下:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace SM4

    {

    public class Sm4

    {

    public const int SM4_ENCRYPT = 1;

    public const int SM4_DECRYPT = 0;

    private long GET_ULONG_BE(byte[] b, int i)

    {

    long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL;

    return n;

    }

    private void PUT_ULONG_BE(long 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 long SHL(long x, int n)

    {

    return (x & 0xFFFFFFFF) << n;

    }

    private long ROTL(long x, int n)

    {

    return SHL(x, n) | x >> (32 - n);

    }

    private void SWAP(long[] sk, int i)

    {

    long t = sk[i];

    sk[i] = sk[(31 - i)];

    sk[(31 - i)] = t;

    }

    public byte[] SboxTable = new byte[] { (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 uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };

    public uint[] 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 long sm4Lt(long ka)

    {

    long bb = 0L;

    long c = 0L;

    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 long sm4F(long x0, long x1, long x2, long x3, long rk)

    {

    return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);

    }

    private long sm4CalciRK(long ka)

    {

    long bb = 0L;

    long rk = 0L;

    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(long[] SK, byte[] key)

    {

    long[] MK = new long[4];

    long[] k = new long[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] ^ (long)FK[0];

    k[1] = MK[1] ^ (long)FK[1];

    k[2] = MK[2] ^ (long)FK[2];

    k[3] = MK[3] ^ (long)FK[3];

    for (; i < 32; i++)

    {

    k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i]));

    SK[i] = k[(i + 4)];

    }

    }

    private void sm4_one_round(long[] sk, byte[] input, byte[] output)

    {

    int i = 0;

    long[] ulbuf = new long[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];

    Array.Copy(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];

    Array.Copy(input, 0, ret, 0, input.Length - p);

    }

    return ret;

    }

    public void sm4_setkey_enc(Sm4Context ctx, byte[] key)

    {

    ctx.mode = SM4_ENCRYPT;

    sm4_setkey(ctx.sk, key);

    }

    public void sm4_setkey_dec(Sm4Context ctx, byte[] key)

    {

    int i = 0;

    ctx.mode = SM4_DECRYPT;

    sm4_setkey(ctx.sk, key);

    for (i = 0; i < 16; i++)

    {

    SWAP(ctx.sk, i);

    }

    }

    public byte[] sm4_crypt_ecb(Sm4Context ctx, byte[] input)

    {

    if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT))

    {

    input = padding(input, SM4_ENCRYPT);

    }

    int length = input.Length;

    byte[] bins = new byte[length];

    Array.Copy(input, 0, bins, 0, length);

    byte[] bous = new byte[length];

    for (int i = 0; length > 0; length -= 16, i++)

    {

    byte[] inBytes = new byte[16];

    byte[] outBytes = new byte[16];

    Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);

    sm4_one_round(ctx.sk, inBytes, outBytes);

    Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length);

    }

    if (ctx.isPadding && ctx.mode == SM4_DECRYPT)

    {

    bous = padding(bous, SM4_DECRYPT);

    }

    return bous;

    }

    public byte[] sm4_crypt_cbc(Sm4Context ctx, byte[] iv, byte[] input)

    {

    if (ctx.isPadding && ctx.mode == SM4_ENCRYPT)

    {

    input = padding(input, SM4_ENCRYPT);

    }

    int i = 0;

    int length = input.Length;

    byte[] bins = new byte[length];

    Array.Copy(input, 0, bins, 0, length);

    byte[] bous = null;

    List bousList = new List();

    if (ctx.mode == SM4_ENCRYPT)

    {

    for (int j = 0; length > 0; length -= 16, j++)

    {

    byte[] inBytes = new byte[16];

    byte[] outBytes = new byte[16];

    byte[] out1 = new byte[16];

    Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);

    for (i = 0; i < 16; i++)

    {

    outBytes[i] = ((byte)(inBytes[i] ^ iv[i]));

    }

    sm4_one_round(ctx.sk, outBytes, out1);

    Array.Copy(out1, 0, iv, 0, 16);

    for (int k = 0; k < 16; k++)

    {

    bousList.Add(out1[k]);

    }

    }

    }

    else

    {

    byte[] temp = new byte[16];

    for (int j = 0; length > 0; length -= 16, j++)

    {

    byte[] inBytes = new byte[16];

    byte[] outBytes = new byte[16];

    byte[] out1 = new byte[16];

    Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);

    Array.Copy(inBytes, 0, temp, 0, 16);

    sm4_one_round(ctx.sk, inBytes, outBytes);

    for (i = 0; i < 16; i++)

    {

    out1[i] = ((byte)(outBytes[i] ^ iv[i]));

    }

    Array.Copy(temp, 0, iv, 0, 16);

    for (int k = 0; k < 16; k++)

    {

    bousList.Add(out1[k]);

    }

    }

    }

    if (ctx.isPadding && ctx.mode == SM4_DECRYPT)

    {

    bous = padding(bousList.ToArray(), SM4_DECRYPT);

    return bous;

    }

    else

    {

    return bousList.ToArray();

    }

    }

    }

    }

    Sm4Context类如下:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace SM4

    {

    public class Sm4Context

    {

    public int mode;

    public long[] sk;

    public bool isPadding;

    public Sm4Context()

    {

    this.mode = 1;

    this.isPadding = true;

    this.sk = new long[32];

    }

    }

    }

    MainSm4类是SM4的访问函数如下

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using Org.BouncyCastle.Utilities.Encoders;

    namespace SM4

    {

    public class MainSm4

    {

    ///

    /// 加密ECB模式

    ///

    /// 密钥

    /// 明文是否是十六进制

    /// 明文

    /// 返回密文

    public String Encrypt_ECB(String secretKey,bool hexString, String plainText)

    {

    Sm4Context ctx = new Sm4Context();

    ctx.isPadding = true;

    ctx.mode = Sm4.SM4_ENCRYPT;

    byte[] keyBytes;

    if (hexString)

    {

    keyBytes = Hex.Decode(secretKey);

    }

    else

    {

    keyBytes = Encoding.Default.GetBytes(secretKey);

    }

    Sm4 sm4 = new Sm4();

    sm4.sm4_setkey_enc(ctx, keyBytes);

    byte[] encrypted = sm4.sm4_crypt_ecb(ctx, Encoding.Default.GetBytes(plainText));

    String cipherText = Encoding.Default.GetString(Hex.Encode(encrypted));

    return cipherText;

    }

    ///

    /// 解密ECB模式

    ///

    /// 密钥

    /// 明文是否是十六进制

    /// 密文

    /// 返回明文

    public String Decrypt_ECB(String secretKey, bool hexString, String cipherText)

    {

    Sm4Context ctx = new Sm4Context();

    ctx.isPadding = true;

    ctx.mode = Sm4.SM4_DECRYPT;

    byte[] keyBytes;

    if (hexString)

    {

    keyBytes = Hex.Decode(secretKey);

    }

    else

    {

    keyBytes = Encoding.Default.GetBytes(secretKey);

    }

    Sm4 sm4 = new Sm4();

    sm4.sm4_setkey_dec(ctx, keyBytes);

    byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherText));

    return Encoding.Default.GetString(decrypted);

    }

    ///

    /// 加密CBC模式

    ///

    /// 密钥

    /// 明文是否是十六进制

    ///

    /// 明文

    /// 返回密文

    public String Encrypt_CBC(String secretKey, bool hexString,string iv, String plainText)

    {

    Sm4Context ctx = new Sm4Context();

    ctx.isPadding = true;

    ctx.mode = Sm4.SM4_ENCRYPT;

    byte[] keyBytes;

    byte[] ivBytes;

    if (hexString)

    {

    keyBytes = Hex.Decode(secretKey);

    ivBytes = Hex.Decode(iv);

    }

    else

    {

    keyBytes = Encoding.Default.GetBytes(secretKey);

    ivBytes = Encoding.Default.GetBytes(iv);

    }

    Sm4 sm4 = new Sm4();

    sm4.sm4_setkey_enc(ctx, keyBytes);

    byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.Default.GetBytes(plainText));

    String cipherText = Encoding.Default.GetString(Hex.Encode(encrypted));

    return cipherText;

    }

    ///

    /// 解密CBC模式

    ///

    /// 密钥

    /// 明文是否是十六进制

    ///

    /// 密文

    /// 返回明文

    public String Decrypt_CBC(String secretKey, bool hexString, string iv, String cipherText)

    {

    Sm4Context ctx = new Sm4Context();

    ctx.isPadding = true;

    ctx.mode = Sm4.SM4_DECRYPT;

    byte[] keyBytes;

    byte[] ivBytes;

    if (hexString)

    {

    keyBytes = Hex.Decode(secretKey);

    ivBytes = Hex.Decode(iv);

    }

    else

    {

    keyBytes = Encoding.Default.GetBytes(secretKey);

    ivBytes = Encoding.Default.GetBytes(iv);

    }

    Sm4 sm4 = new Sm4();

    sm4.sm4_setkey_dec(ctx, keyBytes);

    byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));

    return Encoding.Default.GetString(decrypted);

    }

    }

    }

    设置一下项目,项目右击点属性,

    67b77246ab514691a78f870ad62a271f.png

    5fc475f659723f3d3b0132386e2171f8.png

    c72586be879da9c94c4bf79fc41bb363.png

    然后编译项目。

    下面是C++的项目

    38038b3e3d414e903c8e1640096374e4.png

    创建C++项目(我的项目名和这个不一样)

    7db70e979ef5f2ac0f69a2f94f4037a3.png

    65840ec67804d1405c47c50edc0b778a.png

    C++项目添加引用C#项目。新建源文件 main.cpp,代码如下

    /**********************************

    2017-9-5 21:02:51

    声明需要被java调用的方法,该方法和java接口内部方法保持一致

    预处理语句目的是暴露函数供外部调用。

    ************************/

    #ifdef MYLIBAPI

    #else

    #define  MYLIBAPI  extern "C" __declspec(dllimport)

    #endif

    //添加函数声明

    MYLIBAPI char* Encrypt_ECB(char* secretKey, int hexString, char* plainText);

    MYLIBAPI char* Decrypt_ECB(char* secretKey, int hexString, char* cipherText);

    MYLIBAPI char* Encrypt_CBC(char* secretKey, int hexString, char* iv, char* plainText);

    MYLIBAPI char* Decrypt_CBC(char* secretKey, int hexString, char* iv, char* cipherText);

    using namespace System;

    using namespace SM4;

    //using namespace System::Runtime::InteropServices::m

    char* Encrypt_ECB(char* secretKey, int hexString, char* plainText)

    {

    String ^ secretKeyStr = gcnew String(secretKey);

    String ^ plainTextStr = gcnew String(plainText);

    MainSm4 ^mainsm = gcnew MainSm4();

    String ^resultString = mainsm->Encrypt_ECB(secretKeyStr, hexString, plainTextStr);

    char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);

    return result;

    }

    char* Decrypt_ECB(char* secretKey, int hexString, char* cipherText)

    {

    String ^ secretKeyStr = gcnew String(secretKey);

    String ^ cipherTextStr = gcnew String(cipherText);

    MainSm4 ^mainsm = gcnew MainSm4();

    String ^resultString = mainsm->Decrypt_ECB(secretKeyStr, hexString, cipherTextStr);

    char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);

    return result;

    }

    char* Encrypt_CBC(char* secretKey, int hexString, char* iv, char* plainText)

    {

    String ^ secretKeyStr = gcnew String(secretKey);

    String ^ ivStr = gcnew String(iv);

    String ^ plainTextStr = gcnew String(plainText);

    MainSm4 ^mainsm = gcnew MainSm4();

    String ^resultString = mainsm->Encrypt_CBC(secretKeyStr, hexString, ivStr, plainTextStr);

    char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);

    return result;

    }

    char* Decrypt_CBC(char* secretKey, int hexString, char* iv, char* cipherText)

    {

    String ^ secretKeyStr = gcnew String(secretKey);

    String ^ ivStr = gcnew String(iv);

    String ^ cipherTextStr = gcnew String(cipherText);

    MainSm4 ^mainsm = gcnew MainSm4();

    String ^resultString = mainsm->Decrypt_CBC(secretKeyStr, hexString, ivStr, cipherTextStr);

    char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);

    return result;

    }

    C++项目设置右击属性

    a6bcbd53d88976ac7b4fb52cb72ae142.png

    a204cbb7162408b954ec8243558e3cea.png

    a5be3bc9fd599a385610626adc5ae68c.png

    下面开始Java项目

    b94fd526c77f8b7e1ca878916d7e7aa7.png

    Java项目中要用到 jna的包和jna-platform的包下载地址:https://github.com/java-native-access/jna

    新建Java空项目,在src中添加package:com.xxx.test,然后再包中添加 class文件

    CLibray1如下:

    package com.javaInvokeCsharp.test;

    import com.sun.jna.Library;

    import com.sun.jna.Native;

    /***@ClassName:Clibrary*@Description:TODO*@Author:MiaoZi*@Date:2018-05-14下午 07:01*@Version:1.0**/interface CLibrary1 extends Library {

    //路径为C++的Dll路径

    CLibrary1 INSTANCE= (CLibrary1) Native.

    loadLibrary("D:\\译会C#\\JavaInvokeSm4\\SM4CPP\\Debug\\SM4CPP",

    CLibrary1.class);

    /*需要调用的方法,方法名与c++方法名相同*/

    String Encrypt_ECB(String secretKey,boolean hexString, String plainText);

    String Decrypt_ECB(String secretKey, boolean hexString, String cipherText);

    String Encrypt_CBC(String secretKey, boolean hexString,String iv, String plainText);

    String Decrypt_CBC(String secretKey, boolean hexString, String iv, String cipherText);

    }

    InvokeTest.Java如下:

    package com.javaInvokeCsharp.test;

    import com.sun.jna.Library;

    import com.sun.jna.Native;

    import java.util.*;

    /***@ClassName:InvokeTest*@Description:TODO*@Author:MiaoZi*@Date:2018-05-14下午 06:59*@Version:1.0* 需要引入jna-4.4.0.jar 和 jna-platform-4.4.0* 包下载地址:https://github.com/java-native-access/jna**/class InvokeTest {

    /*** 调用示例*@paramargs*@throwsException*/public static void main(String[] args) throws Exception

    {

    System.out.println(System.getProperty("java.version"));//输出当前jdk版本号

    System.out.println(System.getProperty("sun.arch.data.model"));//输出当前jdk所用平台

    CLibrary1 clib = CLibrary1.INSTANCE;

    //秘钥

    String secretKey="6228480038286822978";

    boolean hexString=false;

    // 要加密的内容

    String plainText="123456";

    String iv="0000000000000000";

    //解密的明文

    String cipherText;

    while (true) {

    Scanner sc = new Scanner(System.in);

    System.out.println("请输入密码:");

    plainText = sc.next();

    System.out.println("明文:" + plainText);

    cipherText = clib.Encrypt_ECB(secretKey, hexString, plainText);

    System.out.println("加密密文:" + cipherText);

    System.out.println("请输入密文:");

    cipherText = sc.next();

    plainText = "";

    plainText = clib.Decrypt_ECB(secretKey, hexString, cipherText);

    System.out.println("解密明文:" + plainText);

    System.out.println( new String(plainText.getBytes(),"ASCII"));

    }

    //System.out.println("测试返回结果:"+cipherText);

    }

    }

    01b2d26bee6cdfbac33a33e73acc2cf7.png

    OK完美实现Java和C#的SM4加密解密问题。

    问题:

    大家运行到这里应该会出错,因为Java可以找到C++的dll,到时没有找到C#的++,怎么办呢,我们需要把C#的Debug目录下的这两个文件拷贝到jak的bin目录里。然后再试一下,就OK啦

    12e4bbe2b61a5c14dcf15db0c3c6fc88.png

    展开全文
  • C# SM4加密

    2021-08-06 18:15:19
    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading....public static int SM4_ENCRYPT = 1; public static int SM4_DECRYPT = 0; p
  • 国密算法SM4-java实现

    2021-12-06 14:49:27
    Maven依赖 org.bouncycastle bcprov-jdk15on 1.56 SM4 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; public class SM4 { protected static final int SM4_ENCRYPT = 1; protected ...
  • C语言实现SM4加解密算法

    千次阅读 2021-11-19 19:45:17
    C语言实现SM4加解密算法SM4加解密 SM4加解密 #include <string.h> #include <stdio.h> #include <time.h> /*---------------------------------------------------------------------------------...
  • appCode、encData 和 signData 参数,同样返回的数据也有这些参数,其加密解密方法是一样的,其中 encType 和 signType 分别为 SM4 和 SM2,所以大概率这是国密算法了,有关国密算法 K 哥前期文章有介绍:《爬虫逆向...
  • php国密sm4

    2021-01-04 09:34:51
    Class SM4Util { public $SM4_CK = [ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249
  • SM1对称密码SM1 算法是分组密码算法,分组长度为128位,密钥长度都为 128 比特,算法安全保密强度及相关软硬件实现性能与 AES 相当,算法不公开,仅以IP核的形式存在于芯片中。采用该算法已经研制了系列芯片、智能IC...
  • SM? SM1? SM2? SM3? SM4?

    2021-02-08 08:00:00
    最近看了一个项目的代码,用到了SM2,SM3,SM4,瞬间懵逼,一会用SM2,一会用SM3,一会又用SM4,SM???简单来说,SM2,SM3,SM4 是国家密码局认定的国产密码算法,当然...
  • 而且因为不是nodeJs环境所以const sm4 = require('sm-crypto').sm4这个在ts里是报错的导致无法实现,如果是使用的是electron那么使用const sm4 = window.require('sm-crypto').sm4就可以来调用js里的方法了。...
  • 1.SM所需包 pom <!--sm加密--> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.69</version...
  • SM4分组加密算法原理和c语言实现

    千次阅读 2021-11-05 17:10:54
    在之前的文章中介绍了《SM3国密杂凑值算法的原理和c语言实现》,这篇文章主要是用c语言撸一个SM4分组加密算法。 随着信息安全的普及以及等级保护等安全政策落地,国密算法越来越频繁的出现在项目开发中,在较新的...
  • SM4算法 C语言 (从OpenSSL库中分离算法:七) OpenSSL简介: OpenSSL 是用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的一个强大、商业级和功能齐全的工具包,它也是一个通用的密码学库。包含有RSA、SM4、DES、...
  • sm4前后端加密集成

    2021-10-16 22:44:19
    pom: <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on<...Sm4Util: package com.zy.platform.common.core.utils; import java.nio
  • SM4国密算法Java版

    2021-02-01 19:10:34
    根据 国密SM4 文档 编写的一个Java 加密解密样例package javasm4;/**** @author Jeen*/public class JavaSM4 {public static int[] key = new int[4];//密钥public static int[] temp = new int[4];//中间量 存储...
  • SM4分组密码算法介绍

    千次阅读 2021-03-03 14:37:54
    SM4无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位,SM4算法主要包含5种基本模式:ECB、CBC、CFB、OFB,CTR(后4种都是ECB算法模块衍生而来);与MAC结合还诞生了GCM,CCM等高级模式。CCM是...
  • SM4对称加密算法及Java实现

    千次阅读 2021-03-12 16:30:32
    一、简介 与DES和AES算法类似,SM4算法是一种分组密码算法。 其分组长度为128bit,密钥长度也为128bit。... 加密算法与密钥扩展算法均采用32轮非线性迭代结构,以字(32位)为...首先,将明文转化为字节,由于SM4
  • PHP实现国密算法SM4

    2021-03-23 21:08:54
    1.SM4算法实现class SM4{const SM4_CK = [0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,0x50575e65, 0x6c737a...
  • 国密算法 SM2 SM3 SM4分别用作什么

    千次阅读 2021-12-05 10:49:07
    非对称加密SM2(可选支持国内SM9)算法实现数据的签名、验签和加解密对称密钥, SM3密码杂凑算法实现数据摘要的生成, 对称密钥SM4加密算法实现对数据内容的加密。
  • 【转】C#实现SM4国密加密

    千次阅读 2021-01-07 16:18:00
    本文主要讲解“国密加密算法”SM系列之SM4的C#实现方法,加密规则请详阅国密局发布的文档。 首先需第三方Nuget包:Portable.BouncyCastle(源码来自http://www.bouncycastle.org/csharp/) 1.1 SM4主类 /// &...
  • PB实现国密SM2/SM3/SM4算法(DLL方式)

    千次阅读 2021-07-04 14:18:38
    文章目录SM4SM3SM2 SM4 SM3 SM2
  • 代码中实现了电码本ECB模式和密文分组连接CBC模式,SM3.java和SM4.java为算法实现类,utils的都是根据实现类写的工具,可以根据需要调用杂凑算法SM3的杂凑功能获得杂凑值。 SM4.java中 sm4_crypt_ecb(SM4_...
  • SM4国密算法java实现

    千次阅读 2021-02-12 21:12:38
    //加密算法/分组加密模式/分组填充方式//PKCS5Padding-以8个字节为一组进行分组加密//定义分组加密模式使用:PKCS5Padding public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 206,677
精华内容 82,670
关键字:

sm4

友情链接: jijiaqi.rar