SMS4 Introduction:
This algorithm is a grouping algorithm. The algorithm has a packet length of 128 bits and a key length of 128 bits, which is 16 bytes. Both the encryption algorithm and the key expansion algorithm adopt 32-round nonlinear iterative structure. Decryption algorithm is the same as the structure of the encryption algorithm, except that the key is used in reverse order, the decryption wheel key is the reverse of the encryption wheel key. All of the basic classes in SMS4, you will see that the underlying function of the encryption and decryption is the same, just need an int type flag bit to determine whether it is encrypted or decrypted.
SMS4 Cryptographic algorithm base class:
public class SMS4 {private static final int ENCRYPT = 1; private static final int DECRYPT = 0; public static final int ROUND = 32; private static final int BLOCK = 16; Private byte[] Sbox = {(byte) 0xd6, (Byte) 0x90, (Byte) 0xe9, (Byte) 0xFE, (Byte) 0xcc, (byte) 0xe1, 0x3d, (by TE) 0xb7, 0x16, (byte) 0xb6, 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, (byte) 0x 9a, 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) 0xa 9, (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, (byt e) 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) 0x AE, 0x5d, (Byte) 0xa4, (byte) 0x9b, 0x34, 0x1a, 0x55, (Byte) 0xad, (byte) 0x93, 0x32, 0x30, (byte) 0 Xf5, (Byte) 0x8c, (byte) 0xb1, (Byte) 0xe3, 0x1d, (Byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, 0x60, (byt e) 0xc0, 0x29, 0x23, (byte) 0xAB, 0x0d, 0x53, 0x4e, 0x6f, (Byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (Byte) 0xde, (b Yte) 0xfd, (byte) 0x8e, 0x2f, 0x03, (byte) 0xFF, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, (byte) 0x8d, 0x 1b, (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, (byt e) 0xbd, 0x2d, 0x74, (byte) 0xd0, 0x12, (Byte) 0xb8, (Byte) 0xe5, (Byte) 0xb4, (Byte) 0xb0, (byte) 0 X89, 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}; Private int[] CK = {0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0XA8AFB6BD, 0XC4CB D2D9, 0XE0E7EEF5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9 , 0xc0c7ced5, 0XDCE3EAF1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0x A0A7AEB5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279}; private int Rotl (int x, int y) {return x << y | x >>> (32-Y); } private int bytesub (int A) {return (Sbox[a >>> & 0xFF] & 0xFF) << 24 | (Sbox[a >>> & 0xFF] & 0xFF) << 16 | (Sbox[a >>> 8 & 0xFF] & 0xFF) << 8 | (Sbox[a & 0xFF] & 0xFF); } private int L1 (int b) {return b ^ rotl (b, 2) ^ Rotl (b, 10) ^ Rotl (b) ^ Rotl (b, 24); Return b^ (b<<2| b>>>30) ^ (b<<10| b>>>22) ^ (b<<18| b>>>14) ^ (b<<24| B>>>8); } private int L2 (int b) {return b ^ rotl (b, i) ^ Rotl (b, 23); Return b^ (b<<13| b>>>19) ^ (b<<23| B>>>9); } void Sms4crypt (byte[] Input, byte[] Output, int[] rk) {int R, Mid, x0, x1, x2, x3; int[] x = new INT[4]; int[] tmp = new INT[4]; for (int i = 0; i < 4; i++) {Tmp[0] = input[0 + 4 * i] & 0xff; TMP[1] = input[1 + 4 * i] & 0xff; TMP[2] = input[2 + 4 * i] & 0xff; TMP[3] = input[3 + 4 * i] & 0xff; X[i] = tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | TMP[3]; X[i]= (input[0+4*i]<<24| input[1+4*i]<<16| Input[2+4*i]<<8|input[3+4*i]); } for (r = 0; R <; r + = 4) {mid = x[1] ^ x[2] ^ X[3] ^ rk[r+ 0]; MID = Bytesub (mid); X[0] = x[0] ^ L1 (mid); X4 mid = x[2] ^ x[3] ^ X[0] ^ Rk[r + 1]; MID = Bytesub (mid); X[1] = x[1] ^ L1 (mid); X5 mid = x[3] ^ x[0] ^ X[1] ^ Rk[r + 2]; MID = Bytesub (mid); X[2] = x[2] ^ L1 (mid); X6 mid = x[0] ^ x[1] ^ X[2] ^ Rk[r + 3]; MID = Bytesub (mid); X[3] = x[3] ^ L1 (mid); X7}//Reverse for (int j = 0; J <; J + = 4) {Output[j] = (byte) (X[3-j/4] & Gt;>> & 0xFF); Output[j + 1] = (byte) (X[3-j/4] >>> & 0xFF); Output[j + 2] = (byte) (X[3-j/4] >>> 8 & 0xFF); Output[j + 3] = (byte) (X[3-j/4] & 0xFF); }} private void Sms4keyext (byte[] Key, int[] rk, int cryptflag) {int R, mid; int[] x = new INT[4]; int[] tmp = new INT[4]; for (int i = 0; i < 4; i++) { Tmp[0] = key[0 + 4 * i] & 0xFF; TMP[1] = key[1 + 4 * i] & 0xff; TMP[2] = key[2 + 4 * i] & 0xff; TMP[3] = key[3 + 4 * i] & 0xff; X[i] = tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | TMP[3]; x[i]=key[0+4*i]<<24| key[1+4*i]<<16| key[2+4*i]<<8|key[3+4*i]; } x[0] ^= 0xa3b1bac6; X[1] ^= 0x56aa3350; X[2] ^= 0x677d9197; X[3] ^= 0xb27022dc; for (r = 0; R <; r + = 4) {mid = x[1] ^ x[2] ^ X[3] ^ ck[r + 0]; MID = Bytesub (mid); Rk[r + 0] = x[0] ^= L2 (mid); RK0=K4 mid = x[2] ^ x[3] ^ X[0] ^ Ck[r + 1]; MID = Bytesub (mid); Rk[r + 1] = x[1] ^= L2 (mid); RK1=K5 mid = x[3] ^ x[0] ^ X[1] ^ Ck[r + 2]; MID = Bytesub (mid); Rk[r + 2] = x[2] ^= L2 (mid); Rk2=k6 mid = x[0] ^ x[1] ^ X[2] ^ Ck[r + 3]; MID = Bytesub (mid); Rk[r + 3] = x[3] ^= L2 (mid); RK3=K7}//decryption wheel key use order: Rk31,rk30,..., rk0 if (Cryptflag = = DECRYPT) {for (r = 0; R < 16; r++) {mid = Rk[r]; RK[R] = Rk[31-r]; Rk[31-r] = mid; }}} public int sms4 (byte[] in, Int. Inlen, byte[] key, byte[] out, int cryptflag) {int-point = 0; int[] Round_key = new Int[round]; Int[] round_key={0}; Sms4keyext (Key, Round_key, Cryptflag); byte[] input = new BYTE[16]; byte[] output = new byte[16]; while (Inlen >= BLOCK) {input = Arrays.copyofrange (in, point, point + 16); Output=arrays.copyofrange (out, point, point+16); Sms4crypt (input, output, round_key); System.arraycopy (output, 0, out, point, BLOCK); Inlen-= BLOCK; Point + = BLOCK; } return 0; }}
Package External interface:
Based on this basic class, it encapsulates the interface, the main interface is as follows:
private static byte[] Encode16 (byte[] plain, byte[] key);p rivate static byte[] Decode16 (byte[] cipher, byte[] key);p rivate Static byte[] Encode32 (byte[] plain, byte[] key);p rivate static byte[] Decode32 (byte[] cipher, byte[] key);p ublic static Byte[] EncodeSMS4 (byte[] plain, byte[] key);p ublic static byte[] decodeSMS4 (byte[] cipher, byte[] key);p ublic static Strin G Decodesms4tostring (byte[] cipher, byte[] key);
Encode16 (byte[], byte[]) is an interface for encrypting 16-bit plaintext and 16-bit keys;
private static byte[] Decode16 (byte[] cipher, byte[] key): Is the interface for 16-bit ciphertext and 16-bit key decryption;
private static byte[] Encode32 (byte[] plain, byte[] key): Is an interface for encrypting 32-bit plaintext and 16-bit keys;
private static byte[] Decode32 (byte[] cipher, byte[] key): Is the interface for 32-bit ciphertext and 16-bit key decryption;
public static byte[] EncodeSMS4 (byte[] plain, byte[] key): An interface for encrypting plaintext and 16-bit keys that are not limited to byte numbers;
public static byte[] DecodeSMS4 (byte[] cipher, byte[] key): It is an interface for decrypting ciphertext and 16-bit keys with no limit to the number of bytes;
public static String decodesms4tostring (byte[] cipher, byte[] key): Is the interface for decrypting ciphertext and 16-bit keys with no limit to the number of bytes;
Use demonstration:
Key byte[] key = {0x01, 0x23, 0x45, 0x67, (Byte) 0x89, (Byte) 0xAB, ( byte) 0xCD, (Byte) 0xEF, (Byte) 0xFE, (byt e) 0xdc, (Byte) 0xba, (byte) 0x98, 0x76, 0x54, 0x32, 0x10}; String newstring = "Coding, Hello!" "; PlainText byte[] enout = SMS4.ENCODESMS4 (newstring, key); if (enout = = null) { return; } SYSTEM.OUT.PRINTLN ("Encrypted result:"); Printbit (enout); byte[] Deout = SMS4.DECODESMS4 (enout, key); System.out.println ("\ nthe decryption result (return byte[]):"); Printbit (deout); String deoutstr = sms4.decodesms4tostring (enout, key); System.out.println ("\ nthe decryption result (return String): \ n" + deoutstr);
Sample Demo Connection:
http://download.csdn.net/detail/u013761665/8357917
Java version SMS4 encryption algorithm