国密算法Java代码的标准实现

摘要:
对于不久前完成的项目,越来越多的金融应用程序使用国家秘密算法进行加密和解密。国家机密是国家加密局认可的国内密码算法。此算法不是公共的。调用此算法时,需要通过加密芯片的接口调用。由于该算法基于ECC,其签名速度和密钥生成速度都比RSA快。对称加密,密钥长度和数据包长度为128位。因为SM1和SM4加密和解密包的大小是128bit,所以在加密和解密消息时,如果消息长度太长,则需要分组。如果消息长度不足,则需要填充。

   前一阵子做的项目,越来越多的金融类应用使用国密算法进行加解密的运算。

    国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。

    SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。

    SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

    SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。

    SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

    由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。

JAVA代码:Util:

国密算法Java代码的标准实现第1张
 import javax.crypto.SecretKey;
  2 import javax.crypto.SecretKeyFactory;
  3 import javax.crypto.spec.PBEKeySpec;
  4 import javax.crypto.spec.SecretKeySpec;
  5 import java.math.BigInteger;
  6 import java.security.NoSuchAlgorithmException;
  7 import java.security.SecureRandom;
  8 import java.security.spec.InvalidKeySpecException;
  9 import java.security.spec.KeySpec;
 10 
 11 public class Util {
 12     public static final byte MAX_VALUE = -1;
 13     public static byte[] hexToByte(String arg8) {
 14         if(arg8.length() % 2 == 0) {
 15             char[] v0 = arg8.toCharArray();
 16             byte[] v1 = new byte[arg8.length() / 2];
 17             int v2 = 0;
 18             int v3 = 0;
 19             int v4 = arg8.length();
 20             while(v2 < v4) {
 21                 StringBuilder v5 = new StringBuilder();
 22                 v5.append("");
 23                 int v6 = v2 + 1;
 24                 v5.append(v0[v2]);
 25                 v5.append(v0[v6]);
 26                 v1[v3] = new Integer(Integer.parseInt(v5.toString(), 16) & 255).byteValue();
 27                 v2 = v6 + 1;
 28                 ++v3;
 29             }
 30 
 31             return v1;
 32         }
 33         throw new IllegalArgumentException();
 34     }
 35     public static String byteToHex(byte[] arg5) {
 36         if(arg5 != null) {
 37             String v0 = "";
 38             int v2;
 39             for(v2 = 0; v2 < arg5.length; ++v2) {
 40                 String v1 = Integer.toHexString(arg5[v2] & 255);
 41                 v0 = v1.length() == 1 ? v0 + "0" + v1 : v0 + v1;
 42             }
 43 
 44             return v0.toUpperCase();
 45         }
 46         throw new IllegalArgumentException("Argument b ( byte array ) is null! ");
 47     }
 48 
 49     public static byte[] byteConvert32Bytes(BigInteger arg5) {
 50         byte[] v0 = null;
 51         if(arg5 == null) {
 52             return v0;
 53         }
 54 
 55         int v4 = 32;
 56         if(arg5.toByteArray().length == 33) {
 57             v0 = new byte[v4];
 58             System.arraycopy(arg5.toByteArray(), 1, v0, 0, v4);
 59         }
 60         else if(arg5.toByteArray().length == v4) {
 61             v0 = arg5.toByteArray();
 62         }
 63         else {
 64             v0 = new byte[v4];
 65             int v1;
 66             for(v1 = 0; v1 < 32 - arg5.toByteArray().length; ++v1) {
 67                 v0[v1] = 0;
 68             }
 69 
 70             System.arraycopy(arg5.toByteArray(), 0, v0, v4 - arg5.toByteArray().length, arg5.toByteArray().length);
 71         }
 72 
 73         return v0;
 74     }
 75 
 76     public static byte[] hexStringToBytes(String arg7) {
 77         if(arg7 != null) {
 78             if(arg7.equals("")) {
 79             }
 80             else {
 81                 arg7 = arg7.toUpperCase();
 82                 int v0 = arg7.length() / 2;
 83                 char[] v1 = arg7.toCharArray();
 84                 byte[] v2 = new byte[v0];
 85                 int v3;
 86                 for(v3 = 0; v3 < v0; ++v3) {
 87                     int v4 = v3 * 2;
 88                     v2[v3] = ((byte)(Util.charToByte(v1[v4]) << 4 | Util.charToByte(v1[v4 + 1])));
 89                 }
 90 
 91                 return v2;
 92             }
 93         }
 94 
 95         return null;
 96     }
 97 
 98     public static byte charToByte(char arg1) {
 99         return ((byte)"0123456789ABCDEF".indexOf(arg1));
100     }
101 
102 }
复制代码
  1 import javax.crypto.SecretKey;
  2 import javax.crypto.SecretKeyFactory;
  3 import javax.crypto.spec.PBEKeySpec;
  4 import javax.crypto.spec.SecretKeySpec;
  5 import java.math.BigInteger;
  6 import java.security.NoSuchAlgorithmException;
  7 import java.security.SecureRandom;
  8 import java.security.spec.InvalidKeySpecException;
  9 import java.security.spec.KeySpec;
 10 
 11 public class Util {
 12     public static final byte MAX_VALUE = -1;
 13     public static byte[] hexToByte(String arg8) {
 14         if(arg8.length() % 2 == 0) {
 15             char[] v0 = arg8.toCharArray();
 16             byte[] v1 = new byte[arg8.length() / 2];
 17             int v2 = 0;
 18             int v3 = 0;
 19             int v4 = arg8.length();
 20             while(v2 < v4) {
 21                 StringBuilder v5 = new StringBuilder();
 22                 v5.append("");
 23                 int v6 = v2 + 1;
 24                 v5.append(v0[v2]);
 25                 v5.append(v0[v6]);
 26                 v1[v3] = new Integer(Integer.parseInt(v5.toString(), 16) & 255).byteValue();
 27                 v2 = v6 + 1;
 28                 ++v3;
 29             }
 30 
 31             return v1;
 32         }
 33         throw new IllegalArgumentException();
 34     }
 35     public static String byteToHex(byte[] arg5) {
 36         if(arg5 != null) {
 37             String v0 = "";
 38             int v2;
 39             for(v2 = 0; v2 < arg5.length; ++v2) {
 40                 String v1 = Integer.toHexString(arg5[v2] & 255);
 41                 v0 = v1.length() == 1 ? v0 + "0" + v1 : v0 + v1;
 42             }
 43 
 44             return v0.toUpperCase();
 45         }
 46         throw new IllegalArgumentException("Argument b ( byte array ) is null! ");
 47     }
 48 
 49     public static byte[] byteConvert32Bytes(BigInteger arg5) {
 50         byte[] v0 = null;
 51         if(arg5 == null) {
 52             return v0;
 53         }
 54 
 55         int v4 = 32;
 56         if(arg5.toByteArray().length == 33) {
 57             v0 = new byte[v4];
 58             System.arraycopy(arg5.toByteArray(), 1, v0, 0, v4);
 59         }
 60         else if(arg5.toByteArray().length == v4) {
 61             v0 = arg5.toByteArray();
 62         }
 63         else {
 64             v0 = new byte[v4];
 65             int v1;
 66             for(v1 = 0; v1 < 32 - arg5.toByteArray().length; ++v1) {
 67                 v0[v1] = 0;
 68             }
 69 
 70             System.arraycopy(arg5.toByteArray(), 0, v0, v4 - arg5.toByteArray().length, arg5.toByteArray().length);
 71         }
 72 
 73         return v0;
 74     }
 75 
 76     public static byte[] hexStringToBytes(String arg7) {
 77         if(arg7 != null) {
 78             if(arg7.equals("")) {
 79             }
 80             else {
 81                 arg7 = arg7.toUpperCase();
 82                 int v0 = arg7.length() / 2;
 83                 char[] v1 = arg7.toCharArray();
 84                 byte[] v2 = new byte[v0];
 85                 int v3;
 86                 for(v3 = 0; v3 < v0; ++v3) {
 87                     int v4 = v3 * 2;
 88                     v2[v3] = ((byte)(Util.charToByte(v1[v4]) << 4 | Util.charToByte(v1[v4 + 1])));
 89                 }
 90 
 91                 return v2;
 92             }
 93         }
 94 
 95         return null;
 96     }
 97 
 98     public static byte charToByte(char arg1) {
 99         return ((byte)"0123456789ABCDEF".indexOf(arg1));
100     }
101 
102 }
复制代码

    SM2:

国密算法Java代码的标准实现第4张
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
 2 import org.bouncycastle.crypto.params.ECDomainParameters;
 3 import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
 4 import org.bouncycastle.math.ec.ECCurve;
 5 import org.bouncycastle.math.ec.ECFieldElement;
 6 import org.bouncycastle.math.ec.ECPoint;
 7 
 8 import java.math.BigInteger;
 9 import java.security.SecureRandom;
10 
11 public class SM2 {
12     public static String[] ecc_param = {"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"};
13     public final BigInteger ecc_p = new BigInteger(ecc_param[0], 16);
14     public final BigInteger ecc_a = new BigInteger(ecc_param[1], 16);
15     public final BigInteger ecc_b = new BigInteger(ecc_param[2], 16);
16     public final BigInteger ecc_n = new BigInteger(ecc_param[3], 16);
17     public final BigInteger ecc_gx = new BigInteger(ecc_param[4], 16);
18     public final BigInteger ecc_gy = new BigInteger(ecc_param[5], 16);
19     public final ECFieldElement ecc_gx_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gx);
20     public final ECFieldElement ecc_gy_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gy);
21     public final ECCurve ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);
22     public final ECPoint ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);
23     public final ECDomainParameters ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);
24     public final ECKeyPairGenerator ecc_key_pair_generator;
25 
26     public static SM2 Instance() {
27         return new SM2();
28     }
29 
30     public SM2() {
31         ECKeyGenerationParameters ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());
32         this.ecc_key_pair_generator = new ECKeyPairGenerator();
33         this.ecc_key_pair_generator.init(ecc_ecgenparam);
34     }
35 }

    SM2Util:

国密算法Java代码的标准实现第5张 
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
 2 import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
 3 import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
 4 import org.bouncycastle.crypto.params.ECPublicKeyParameters;
 5 import org.bouncycastle.math.ec.ECPoint;
 6 
 7 import java.io.IOException;
 8 import java.math.BigInteger;
 9 
10 public class SM2Util {
11     public static final String PUBLIC_KEY = "你的公钥1";
12     public static final String PUBLIC_KEY_2 = "你的公钥2";
13     public static String encrypt(String key, String mes) {
14         byte[] arg9 = mes.getBytes();
15         byte[] arg8 = Util.hexToByte(key);
16         String v0 = null;
17         if(arg8 != null) {
18             if(arg8.length == 0) {
19             }
20             else {
21                 if(arg9 != null) {
22                     if(arg9.length == 0) {
23                     }
24                     else {
25                         byte[] v0_1 = new byte[arg9.length];
26                         System.arraycopy(arg9, 0, v0_1, 0, arg9.length);
27                         Cipher v1 = new Cipher();
28                         SM2 v2 = SM2.Instance();
29                         ECPoint v4 = v1.Init_enc(v2, v2.ecc_curve.decodePoint(arg8));
30                         v1.Encrypt(v0_1);
31                         byte[] v5 = new byte[32];
32                         v1.Dofinal(v5);
33                         return Util.byteToHex(v4.getEncoded()) + Util.byteToHex(v5) + Util.byteToHex(v0_1);
34                     }
35                 }
36                 return v0;
37             }
38         }
39         return v0;
40     }
41 
42     public static String decrypt(String key, String mes) throws IOException {
43         byte[] arg9 = Util.hexToByte(key);
44         byte[] arg10 = Util.hexToByte(mes);
45         byte[] v0 = null;
46         if(arg9 != null) {
47             if(arg9.length == 0) {
48             }
49             else {
50                 if(arg10 != null) {
51                     if(arg10.length == 0) {
52                     }
53                     else {
54                         String v0_1 = Util.byteToHex(arg10);
55                         byte[] v1 = Util.hexToByte(v0_1.substring(0, 130));
56                         int v3 = arg10.length - 97;
57                         byte[] v2 = Util.hexToByte(v0_1.substring(130, 194));
58                         byte[] v4 = Util.hexToByte(v0_1.substring(194, v3 * 2 + 194));
59                         SM2 v5 = SM2.Instance();
60                         BigInteger v6 = new BigInteger(1, arg9);
61                         ECPoint v7 = v5.ecc_curve.decodePoint(v1);
62                         Cipher v8 = new Cipher();
63                         v8.Init_dec(v6, v7);
64                         v8.Decrypt(v4);
65                         v8.Dofinal(v2);
66                         return new String(v4);
67                     }
68                 }
69 
70                 return new String(v0);
71             }
72         }
73         return new String(v0);
74     }
75 
76 //    public static SM2KeyVO generateKeyPair() {
77 //        AsymmetricCipherKeyPair v1;
78 //        SM2 v0 = SM2.Instance();
79 //        while(true) {
80 //            v1 = v0.ecc_key_pair_generator.generateKeyPair();
81 //            if(v1.getPrivate().getD().toByteArray().length == 32) {
82 //                break;
83 //            }
84 //        }
85 //
86 //        AsymmetricKeyParameter v2 = v1.getPrivate();
87 //        AsymmetricKeyParameter v3 = v1.getPublic();
88 //        BigInteger v4 = ((ECPrivateKeyParameters)v2).getD();
89 //        ECPoint v5 = ((ECPublicKeyParameters)v3).getQ();
90 //        SM2KeyVO v6 = new SM2KeyVO();
91 //        v6.setPublicKey(v5);
92 //        v6.setPrivateKey(v4);
93 //        return v6;
94 //    }
95 
96 }

    SM2KeyVO:

国密算法Java代码的标准实现第6张 
import org.bouncycastle.math.ec.ECPoint;
 2 
 3 import java.math.BigInteger;
 4 
 5 public class SM2KeyVO {
 6     BigInteger privateKey;
 7     ECPoint publicKey;
 8 
 9     public String getPriHexInSoft() {
10         return Util.byteToHex(this.privateKey.toByteArray());
11     }
12 
13     public BigInteger getPrivateKey() {
14         return this.privateKey;
15     }
16 
17     public String getPubHexInSoft() {
18         return Util.byteToHex(this.publicKey.getEncoded());
19     }
20 
21     public ECPoint getPublicKey() {
22         return this.publicKey;
23     }
24 
25     public void setPrivateKey(BigInteger arg1) {
26         this.privateKey = arg1;
27     }
28 
29     public void setPublicKey(ECPoint arg1) {
30         this.publicKey = arg1;
31     }
32 }
复制代码

    SM3Util:

国密算法Java代码的标准实现第8张 
import org.bouncycastle.crypto.digests.SM3Digest;
 2 import org.bouncycastle.util.encoders.Hex;
 3 
 4 public class SM3Util {
 5     public static String sm3(String arg5) {
 6         byte[] v0 = new byte[32];
 7         byte[] v1 = arg5.getBytes();
 8         SM3Digest v2 = new SM3Digest();
 9         v2.update(v1, 0, v1.length);
10         v2.doFinal(v0, 0);
11         return new String(Hex.encode(v0)).toUpperCase();
12     }
13 }

    SM4:

国密算法Java代码的标准实现第9张 
import java.io.ByteArrayInputStream;
  2 import java.io.ByteArrayOutputStream;
  3 
  4 public class SM4 {
  5     public static final int[] CK = new int[]{462357, 472066609, 943670861, 1415275113, 1886879365, -1936483679, -1464879427, -993275175, -521670923, -66909679, 404694573, 876298825, 1347903077, 1819507329, -2003855715, -1532251463, -1060647211, -589042959, -117504499, 337322537, 808926789, 1280531041, 1752135293, -2071227751, -1599623499, -1128019247, -656414995, -184876535, 269950501, 741554753, 1213159005, 1684763257};
  6     public static final int[] FK = new int[]{-1548633402, 1453994832, 1736282519, -1301273892};
  7     public static final int SM4_DECRYPT = 0;
  8     public static final int SM4_ENCRYPT = 1;
  9     public static final byte[] SboxTable = new byte[]{-42, -112, -23, -2, -52, -31, 61, -73, 22, -74, 20, -62, 40, -5, 44, 5, 43, 103, -102, 118, 42, -66, 4, -61, -86, 68, 19, 38, 73, -122, 6, -103, -100, 66, 80, -12, -111, -17, -104, 122, 51, 84, 11, 67, -19, -49, -84, 98, -28, -77, 28, -87, -55, 8, -24, -107, -128, -33, -108, -6, 117, -113, 63, -90, 71, 7, -89, -4, -13, 115, 23, -70, -125, 89, 60, 25, -26, -123, 79, -88, 104, 107, -127, -78, 113, 100, -38, -117, -8, -21, 15, 75, 112, 86, -99, 53, 30, 36, 14, 94, 99, 88, -47, -94, 37, 34, 124, 59, 1, 33, 120, -121, -44, 0, 70, 87, -97, -45, 39, 82, 76, 54, 2, -25, -96, -60, -56, -98, -22, -65, -118, -46, 64, -57, 56, -75, -93, -9, -14, -50, -7, 97, 21, -95, -32, -82, 93, -92, -101, 52, 26, 85, -83, -109, 50, 48, -11, -116, -79, -29, 29, -10, -30, 46, -126, 102, -54, 96, -64, 41, 35, -85, 13, 83, 78, 111, -43, -37, 55, 69, -34, -3, -114, 47, 3, -1, 106, 114, 109, 108, 91, 81, -115, 27, -81, -110, -69, -35, -68, 127, 17, -39, 92, 65, 31, 16, 90, -40, 10, -63, 49, -120, -91, -51, 123, -67, 45, 116, -48, 18, -72, -27, -76, -80, -119, 105, -105, 74, 12, -106, 119, 126, 101, -71, -15, 9, -59, 110, -58, -124, 24, -16, 125, -20, 58, -36, 77, 32, 121, -18, 95, 62, -41, -53, 57, 72};
 10 
 11     public SM4() {
 12         super();
 13     }
 14 
 15     private long GET_ULONG_BE(byte[] arg7, int arg8) {
 16         return (((long)(arg7[arg8] & 255))) << 24 | (((long)((arg7[arg8 + 1] & 255) << 16))) | (((long)((arg7[arg8 + 2] & 255) << 8))) | (((long)(arg7[arg8 + 3] & 255))) & 4294967295L;
 17     }
 18 
 19     private void PUT_ULONG_BE(long arg7, byte[] arg9, int arg10) {
 20         arg9[arg10] = ((byte)(((int)(arg7 >> 24 & 255))));
 21         arg9[arg10 + 1] = ((byte)(((int)(arg7 >> 16 & 255))));
 22         arg9[arg10 + 2] = ((byte)(((int)(arg7 >> 8 & 255))));
 23         arg9[arg10 + 3] = ((byte)(((int)(arg7 & 255))));
 24     }
 25 
 26     private long ROTL(long arg5, int arg7) {
 27         return this.SHL(arg5, arg7) | arg5 >> 32 - arg7;
 28     }
 29 
 30     private long SHL(long arg3, int arg5) {
 31         return (-1 & arg3) << arg5;
 32     }
 33 
 34     private void SWAP(long[] arg5, int arg6) {
 35         long v0 = arg5[arg6];
 36         arg5[arg6] = arg5[31 - arg6];
 37         arg5[31 - arg6] = v0;
 38     }
 39 
 40     private byte[] padding(byte[] arg6, int arg7) {
 41         int v1;
 42         byte[] v0 = null;
 43         if(arg6 == null) {
 44             return v0;
 45         }
 46 
 47         if(arg7 == 1) {
 48             v1 = 16 - arg6.length % 16;
 49             v0 = new byte[arg6.length + v1];
 50             System.arraycopy(arg6, 0, v0, 0, arg6.length);
 51             int v2;
 52             for(v2 = 0; v2 < v1; ++v2) {
 53                 v0[arg6.length + v2] = ((byte)v1);
 54             }
 55         }
 56         else {
 57             v1 = arg6[arg6.length - 1];
 58             v0 = new byte[arg6.length - v1];
 59             System.arraycopy(arg6, 0, v0, 0, arg6.length - v1);
 60         }
 61 
 62         return v0;
 63     }
 64 
 65     private long sm4CalciRK(long arg11) {
 66         byte[] v5 = new byte[4];
 67         byte[] v4 = new byte[4];
 68         this.PUT_ULONG_BE(arg11, v5, 0);
 69         v4[0] = this.sm4Sbox(v5[0]);
 70         v4[1] = this.sm4Sbox(v5[1]);
 71         v4[2] = this.sm4Sbox(v5[2]);
 72         v4[3] = this.sm4Sbox(v5[3]);
 73         long v0 = this.GET_ULONG_BE(v4, 0);
 74         return this.ROTL(v0, 13) ^ v0 ^ this.ROTL(v0, 23);
 75     }
 76 
 77     private long sm4F(long arg3, long arg5, long arg7, long arg9, long arg11) {
 78         return this.sm4Lt(arg5 ^ arg7 ^ arg9 ^ arg11) ^ arg3;
 79     }
 80 
 81     private long sm4Lt(long arg11) {
 82         byte[] v5 = new byte[4];
 83         byte[] v4 = new byte[4];
 84         this.PUT_ULONG_BE(arg11, v5, 0);
 85         v4[0] = this.sm4Sbox(v5[0]);
 86         v4[1] = this.sm4Sbox(v5[1]);
 87         v4[2] = this.sm4Sbox(v5[2]);
 88         v4[3] = this.sm4Sbox(v5[3]);
 89         long v0 = this.GET_ULONG_BE(v4, 0);
 90         return this.ROTL(v0, 2) ^ v0 ^ this.ROTL(v0, 10) ^ this.ROTL(v0, 18) ^ this.ROTL(v0, 24);
 91     }
 92 
 93     private byte sm4Sbox(byte arg3) {
 94         return SM4.SboxTable[arg3 & 255];
 95     }
 96 
 97     public byte[] sm4_crypt_cbc(SM4_Context arg13, byte[] arg14, byte[] arg15) throws Exception {
 98         byte[] v8;
 99         byte[] v6;
100         byte[] v2;
101         if(arg14 != null) {
102             int v1 = 16;
103             if(arg14.length == v1) {
104                 if(arg15 != null) {
105                     if((arg13.isPadding) && arg13.mode == 1) {
106                         arg15 = this.padding(arg15, 1);
107                     }
108 
109                     int v3 = arg15.length;
110                     ByteArrayInputStream v4 = new ByteArrayInputStream(arg15);
111                     ByteArrayOutputStream v5 = new ByteArrayOutputStream();
112                     if(arg13.mode == 1) {
113                         while(v3 > 0) {
114                             v2 = new byte[v1];
115                             v6 = new byte[v1];
116                             v8 = new byte[v1];
117                             v4.read(v2);
118                             int v0;
119                             for(v0 = 0; v0 < v1; ++v0) {
120                                 v6[v0] = ((byte)(v2[v0] ^ arg14[v0]));
121                             }
122 
123                             this.sm4_one_round(arg13.sk, v6, v8);
124                             System.arraycopy(v8, 0, arg14, 0, v1);
125                             v5.write(v8);
126                             v3 += -16;
127                         }
128                     }
129                     else {
130                         v2 = new byte[v1];
131                         while(v3 > 0) {
132                             v6 = new byte[v1];
133                             v8 = new byte[v1];
134                             byte[] v9 = new byte[v1];
135                             v4.read(v6);
136                             System.arraycopy(v6, 0, v2, 0, v1);
137                             this.sm4_one_round(arg13.sk, v6, v8);
138                             int v0;
139                             for(v0 = 0; v0 < v1; ++v0) {
140                                 v9[v0] = ((byte)(v8[v0] ^ arg14[v0]));
141                             }
142 
143                             System.arraycopy(v2, 0, arg14, 0, v1);
144                             v5.write(v9);
145                             v3 += -16;
146                         }
147                     }
148 
149                     byte[] v1_1 = v5.toByteArray();
150                     if((arg13.isPadding) && arg13.mode == 0) {
151                         v1_1 = this.padding(v1_1, 0);
152                     }
153 
154                     v4.close();
155                     v5.close();
156                     return v1_1;
157                 }
158                 else {
159                     throw new Exception("input is null!");
160                 }
161             }
162         }
163 
164         throw new Exception("iv error!");
165     }
166 
167     public byte[] sm4_crypt_ecb(SM4_Context arg7, byte[] arg8) throws Exception {
168         byte[] v3;
169         if(arg8 != null) {
170             if((arg7.isPadding) && arg7.mode == 1) {
171                 arg8 = this.padding(arg8, 1);
172             }
173 
174             int v0 = arg8.length;
175             ByteArrayInputStream v1 = new ByteArrayInputStream(arg8);
176             ByteArrayOutputStream v2 = new ByteArrayOutputStream();
177             while(v0 > 0) {
178                 byte[] v4 = new byte[16];
179                 v3 = new byte[16];
180                 v1.read(v4);
181                 this.sm4_one_round(arg7.sk, v4, v3);
182                 v2.write(v3);
183                 v0 += -16;
184             }
185 
186             v3 = v2.toByteArray();
187             if((arg7.isPadding) && arg7.mode == 0) {
188                 v3 = this.padding(v3, 0);
189             }
190 
191             v1.close();
192             v2.close();
193             return v3;
194         }
195 
196         throw new Exception("input is null!");
197     }
198 
199     private void sm4_one_round(long[] arg23, byte[] arg24, byte[] arg25) {
200         int v0;
201         SM4 v11 = this;
202         byte[] v13 = arg25;
203         long[] v14 = new long[36];
204         v14[0] = v11.GET_ULONG_BE(arg24, 0);
205         v14[1] = v11.GET_ULONG_BE(arg24, 4);
206         v14[2] = v11.GET_ULONG_BE(arg24, 8);
207         v14[3] = v11.GET_ULONG_BE(arg24, 12);
208         int v8;
209         for(v8 = 0; true; ++v8) {
210             v0 = 32;
211             if(v8 >= v0) {
212                 break;
213             }
214 
215             v14[v8 + 4] = this.sm4F(v14[v8], v14[v8 + 1], v14[v8 + 2], v14[v8 + 3], arg23[v8]);
216         }
217 
218         v11.PUT_ULONG_BE(v14[35], v13, 0);
219         v11.PUT_ULONG_BE(v14[34], v13, 4);
220         v11.PUT_ULONG_BE(v14[33], v13, 8);
221         v11.PUT_ULONG_BE(v14[v0], v13, 12);
222     }
223 
224     private void sm4_setkey(long[] arg13, byte[] arg14) {
225         long[] v1 = new long[4];
226         long[] v2 = new long[36];
227         int v3 = 0;
228         v1[0] = this.GET_ULONG_BE(arg14, 0);
229         v1[1] = this.GET_ULONG_BE(arg14, 4);
230         v1[2] = this.GET_ULONG_BE(arg14, 8);
231         v1[3] = this.GET_ULONG_BE(arg14, 12);
232         long v5 = v1[0];
233         int[] v9 = SM4.FK;
234         v2[0] = v5 ^ (((long)v9[0]));
235         v2[1] = v1[1] ^ (((long)v9[1]));
236         v2[2] = v1[2] ^ (((long)v9[2]));
237         v2[3] = v1[3] ^ (((long)v9[3]));
238         while(v3 < 32) {
239             v2[v3 + 4] = v2[v3] ^ this.sm4CalciRK(v2[v3 + 1] ^ v2[v3 + 2] ^ v2[v3 + 3] ^ (((long)SM4.CK[v3])));
240             arg13[v3] = v2[v3 + 4];
241             ++v3;
242         }
243     }
244 
245     public void sm4_setkey_dec(SM4_Context arg4, byte[] arg5) throws Exception {
246         if(arg4 != null) {
247             if(arg5 != null) {
248                 int v1 = 16;
249                 if(arg5.length == v1) {
250                     arg4.mode = 0;
251                     this.sm4_setkey(arg4.sk, arg5);
252                     int v0;
253                     for(v0 = 0; v0 < v1; ++v0) {
254                         this.SWAP(arg4.sk, v0);
255                     }
256 
257                     return;
258                 }
259             }
260 
261             throw new Exception("key error!");
262         }
263 
264         throw new Exception("ctx is null!");
265     }
266 
267     public void sm4_setkey_enc(SM4_Context arg3, byte[] arg4) throws Exception {
268         if(arg3 != null) {
269             if(arg4 != null && arg4.length == 16) {
270                 arg3.mode = 1;
271                 this.sm4_setkey(arg3.sk, arg4);
272                 return;
273             }
274 
275             throw new Exception("key error!");
276         }
277 
278         throw new Exception("ctx is null!");
279     }
280 }

    SM4_Context:

国密算法Java代码的标准实现第10张 
public class SM4_Context {
 2     public boolean isPadding;
 3     public int mode;
 4     public long[] sk;
 5 
 6     public SM4_Context() {
 7         super();
 8         this.mode = 1;
 9         this.isPadding = true;
10         this.sk = new long[32];
11     }
12 }

    SM4Util:

国密算法Java代码的标准实现第1张
import org.apache.commons.codec.binary.Base64;
  2 
  3 import java.io.IOException;
  4 import java.io.PrintStream;
  5 import java.util.regex.Pattern;
  6 
  7 public class SM4Utils {
  8     public static final String KEY = "你的key";
  9     public static final String IV = "你的IV";
 10     public boolean hexString;
 11     public String iv;
 12     public String secretKey;
 13 
 14     public SM4Utils() {
 15         super();
 16         this.secretKey = "";
 17         this.iv = "";
 18         this.hexString = false;
 19     }
 20 
 21     public static String sm4Decrypt(String mes) {
 22         SM4Utils v0 = new SM4Utils();
 23         v0.secretKey = KEY;
 24         v0.iv = IV;
 25         v0.hexString = true;
 26         return v0.decryptData_CBC(mes);
 27     }
 28 
 29     public static String sm4Encrypt(String mes) {
 30         SM4Utils v0 = new SM4Utils();
 31         v0.secretKey = KEY;
 32         v0.iv = IV;
 33         v0.hexString = true;
 34         return v0.encryptData_CBC(mes);
 35     }
 36 
 37     public String decryptData_CBC(String arg9) {
 38         byte[] v3;
 39         byte[] v2;
 40         try {
 41             arg9 = Base64.encodeBase64String(Util.hexToByte(arg9));
 42             if(arg9 != null && arg9.trim().length() > 0) {
 43                 arg9 = Pattern.compile("\s*|	|
|
").matcher(((CharSequence)arg9)).replaceAll("");
 44             }
 45 
 46             SM4_Context v1 = new SM4_Context();
 47             v1.isPadding = true;
 48             v1.mode = 0;
 49             if(this.hexString) {
 50                 v2 = Util.hexStringToBytes(this.secretKey);
 51                 v3 = Util.hexStringToBytes(this.iv);
 52             }
 53             else {
 54                 v2 = this.secretKey.getBytes();
 55                 v3 = this.iv.getBytes();
 56             }
 57 
 58             SM4 v4 = new SM4();
 59             v4.sm4_setkey_dec(v1, v2);
 60             return new String(v4.sm4_crypt_cbc(v1, v3, Base64.decodeBase64(arg9)), "UTF-8");
 61         }
 62         catch(Exception v0) {
 63             v0.printStackTrace();
 64             return null;
 65         }
 66     }
 67 
 68     public String encryptData_CBC(String arg7) {
 69         byte[] v2;
 70         byte[] v1;
 71         try {
 72             SM4_Context v0_1 = new SM4_Context();
 73             v0_1.isPadding = true;
 74             v0_1.mode = 1;
 75             if(this.hexString) {
 76                 v1 = Util.hexStringToBytes(this.secretKey);
 77                 v2 = Util.hexStringToBytes(this.iv);
 78             }
 79             else {
 80                 v1 = this.secretKey.getBytes();
 81                 v2 = this.iv.getBytes();
 82             }
 83 
 84             SM4 v3 = new SM4();
 85             v3.sm4_setkey_enc(v0_1, v1);
 86             return Util.byteToHex(v3.sm4_crypt_cbc(v0_1, v2, arg7.getBytes("UTF-8")));
 87         }
 88         catch(Exception v0) {
 89             v0.printStackTrace();
 90             return null;
 91         }
 92     }
 93 
 94     public String decryptData_ECB(String arg8) {
 95         try {
 96             arg8 = Base64.encodeBase64String(Util.hexToByte(arg8));
 97             if(arg8 != null && arg8.trim().length() > 0) {
 98                 arg8 = Pattern.compile("\s*|	|
|
").matcher(((CharSequence)arg8)).replaceAll("");
 99             }
100 
101             SM4_Context v1 = new SM4_Context();
102             v1.isPadding = true;
103             v1.mode = 0;
104             byte[] v2 = this.hexString ? Util.hexStringToBytes(this.secretKey) : this.secretKey.getBytes();
105             SM4 v3 = new SM4();
106             v3.sm4_setkey_dec(v1, v2);
107             return new String(v3.sm4_crypt_ecb(v1, Base64.decodeBase64(arg8)), "UTF-8");
108         }
109         catch(Exception v0) {
110             v0.printStackTrace();
111             return null;
112         }
113     }
114 
115     public String encryptData_ECB(String arg6) {
116         try {
117             SM4_Context v0_1 = new SM4_Context();
118             v0_1.isPadding = true;
119             v0_1.mode = 1;
120             byte[] v1 = this.hexString ? Util.hexStringToBytes(this.secretKey) : Util.hexStringToBytes(this.secretKey);
121             SM4 v2 = new SM4();
122             v2.sm4_setkey_enc(v0_1, v1);
123             return Util.byteToHex(v2.sm4_crypt_ecb(v0_1, arg6.getBytes("UTF-8")));
124         }
125         catch(Exception v0) {
126             v0.printStackTrace();
127             return null;
128         }
129     }
130 
131 }
复制代码
  1 import org.apache.commons.codec.binary.Base64;
  2 
  3 import java.io.IOException;
  4 import java.io.PrintStream;
  5 import java.util.regex.Pattern;
  6 
  7 public class SM4Utils {
  8     public static final String KEY = "你的key";
  9     public static final String IV = "你的IV";
 10     public boolean hexString;
 11     public String iv;
 12     public String secretKey;
 13 
 14     public SM4Utils() {
 15         super();
 16         this.secretKey = "";
 17         this.iv = "";
 18         this.hexString = false;
 19     }
 20 
 21     public static String sm4Decrypt(String mes) {
 22         SM4Utils v0 = new SM4Utils();
 23         v0.secretKey = KEY;
 24         v0.iv = IV;
 25         v0.hexString = true;
 26         return v0.decryptData_CBC(mes);
 27     }
 28 
 29     public static String sm4Encrypt(String mes) {
 30         SM4Utils v0 = new SM4Utils();
 31         v0.secretKey = KEY;
 32         v0.iv = IV;
 33         v0.hexString = true;
 34         return v0.encryptData_CBC(mes);
 35     }
 36 
 37     public String decryptData_CBC(String arg9) {
 38         byte[] v3;
 39         byte[] v2;
 40         try {
 41             arg9 = Base64.encodeBase64String(Util.hexToByte(arg9));
 42             if(arg9 != null && arg9.trim().length() > 0) {
 43                 arg9 = Pattern.compile("\s*|	|
|
").matcher(((CharSequence)arg9)).replaceAll("");
 44             }
 45 
 46             SM4_Context v1 = new SM4_Context();
 47             v1.isPadding = true;
 48             v1.mode = 0;
 49             if(this.hexString) {
 50                 v2 = Util.hexStringToBytes(this.secretKey);
 51                 v3 = Util.hexStringToBytes(this.iv);
 52             }
 53             else {
 54                 v2 = this.secretKey.getBytes();
 55                 v3 = this.iv.getBytes();
 56             }
 57 
 58             SM4 v4 = new SM4();
 59             v4.sm4_setkey_dec(v1, v2);
 60             return new String(v4.sm4_crypt_cbc(v1, v3, Base64.decodeBase64(arg9)), "UTF-8");
 61         }
 62         catch(Exception v0) {
 63             v0.printStackTrace();
 64             return null;
 65         }
 66     }
 67 
 68     public String encryptData_CBC(String arg7) {
 69         byte[] v2;
 70         byte[] v1;
 71         try {
 72             SM4_Context v0_1 = new SM4_Context();
 73             v0_1.isPadding = true;
 74             v0_1.mode = 1;
 75             if(this.hexString) {
 76                 v1 = Util.hexStringToBytes(this.secretKey);
 77                 v2 = Util.hexStringToBytes(this.iv);
 78             }
 79             else {
 80                 v1 = this.secretKey.getBytes();
 81                 v2 = this.iv.getBytes();
 82             }
 83 
 84             SM4 v3 = new SM4();
 85             v3.sm4_setkey_enc(v0_1, v1);
 86             return Util.byteToHex(v3.sm4_crypt_cbc(v0_1, v2, arg7.getBytes("UTF-8")));
 87         }
 88         catch(Exception v0) {
 89             v0.printStackTrace();
 90             return null;
 91         }
 92     }
 93 
 94     public String decryptData_ECB(String arg8) {
 95         try {
 96             arg8 = Base64.encodeBase64String(Util.hexToByte(arg8));
 97             if(arg8 != null && arg8.trim().length() > 0) {
 98                 arg8 = Pattern.compile("\s*|	|
|
").matcher(((CharSequence)arg8)).replaceAll("");
 99             }
100 
101             SM4_Context v1 = new SM4_Context();
102             v1.isPadding = true;
103             v1.mode = 0;
104             byte[] v2 = this.hexString ? Util.hexStringToBytes(this.secretKey) : this.secretKey.getBytes();
105             SM4 v3 = new SM4();
106             v3.sm4_setkey_dec(v1, v2);
107             return new String(v3.sm4_crypt_ecb(v1, Base64.decodeBase64(arg8)), "UTF-8");
108         }
109         catch(Exception v0) {
110             v0.printStackTrace();
111             return null;
112         }
113     }
114 
115     public String encryptData_ECB(String arg6) {
116         try {
117             SM4_Context v0_1 = new SM4_Context();
118             v0_1.isPadding = true;
119             v0_1.mode = 1;
120             byte[] v1 = this.hexString ? Util.hexStringToBytes(this.secretKey) : Util.hexStringToBytes(this.secretKey);
121             SM4 v2 = new SM4();
122             v2.sm4_setkey_enc(v0_1, v1);
123             return Util.byteToHex(v2.sm4_crypt_ecb(v0_1, arg6.getBytes("UTF-8")));
124         }
125         catch(Exception v0) {
126             v0.printStackTrace();
127             return null;
128         }
129     }
130 
131 }
复制代码

    需要导入的jar:

链接:https://pan.baidu.com/s/1ywPfsQvWAyN8UHRXoAHodw  密码:x1gy

免责声明:文章转载自《国密算法Java代码的标准实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇开机自动mountIDEA通过Maven打包JavaFX工程(OpenJFX11)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java 常用类(二):包装类(Wrapper)

一、包装类概述   1、为什么需要包装类     Java并不是纯面向对象的语言。Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。基本数据类型有它的优势:性能(效率高,节省空间)。        在实际使用中经常需要将基本数据类型转成对象,这时就需要将基本数据类型数据转化为对象。   2、包装类     Java 提供了两个...

踩坑系列—SqlServer批量新增BigDecimal精度问题&amp;lt;foreach collection="list" item="item" separator="," index="index"&amp;gt;&amp;lt;/foreach&amp;gt;

Insert into ALU_KINGDEE_POWDER_STORE(org_code,verify_date,material_code,material_name,brand,storage,type,weight)VALUES (?,?,?,?,?,?,?,?) , (?,?,?,?,?,?,?,?) ; 11:51:55 [qtp20145...

natapp自动获取免费的动态端口域名

前段时间,因为客户有个项目要求跨局域网进行远程控制桌面,想知道能不能实现。于是查询了许多资料,了解到需要有公网服务器作为中介才能够实现,但是公司又没有公网服务器,于是只有利用花生壳、natapp服务器实现内网穿透服务。但是这些都要收费,免费的域名和端口是随机变动的,对于测试相当不方便。于是就想设计一款工具能够自动获取natapp产生的动态域名与端口。申请n...

SystemProperties.get/set property_get/set

在java层设置系统属性要注意几点: 1 需要有系统权限。可以在AndroidManifest.xml添加android:sharedUserId="android.uid.system",并且通过系统签名来获取系统权限。 2 需要注意有几点,key的开头必须要符合property_perms中的定义规范,如下面的定义:一定要符合prefix,uid,gi...

java(计算机)常见加密算法详解

  来源:http://blog.csdn.net/janronehoo/article/category/1152295  如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorithm,安全散列算法) HMA...

Gradle配置最佳实践

https://blog.csdn.net/devilnov/article/details/53321164 本文会不定期更新,推荐watch下项目。如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以提交pull request。本文意在分享作者在实践中掌握的关于gradle的一些技巧。 本文固定连接:https://github...