Cryptography on the Growth Path of Programmers - Detailed Explanation of AES Algorithm Decryption and Code Presentation

Hello, everyone on csdn, I am back again. This article is a companion article to the last introduction to the AES encryption algorithm. The focus will be on the decryption process of the AES algorithm and the code for AES encryption and decryption. [Temporarily does not include iv or offset]. Please follow me into the world of AES decryption.

Detailed explanation of AES encryption

If you have any questions about the AES algorithm or AES encryption, you can refer to my previous article.
https://blog.csdn.net/qq_31236027/article/details/129796471

AES decryption

Compared with DES decryption, which only needs to exchange the order of the key group, AES decryption will become more cumbersome.

overall process

Assuming that everyone understands the encryption process of AES, then we know that there are 11 rounds of encryption, and the same is true for decryption. In the first round of encryption, only one round of key addition is performed, and in the last round of encryption, no column confusion is required. The decryption process is just the opposite. For decryption, it first reverses the last round of encryption, and then recursively moves forward until the first round of encryption is reversed, as shown in the figure below.
insert image description here
After understanding the complete process, let's use the "divide and conquer" idea to explain the difficulties separately.

round key plus

The key participates in the operation from the back to the front, that is, the key of the last round of encryption participates in the first round of decryption. For the convenience of programming, we can use global variables to store encryption and decryption keys. Here I will not introduce too much about the arrangement principle of the key. If you have any questions, please refer to my previous blog about AES encryption.

reverse row shift

In the AES encryption algorithm, the row shifting
first row remains unchanged, the second row is cyclically shifted to the left by one bit, the third row is cyclically shifted to the left by two bits, and the fourth row is cyclically shifted to the left by three bits.
insert image description here
That is to say, B[0][1] -> B[1][2] in the original 4*4 matrix (B1 -> B5 in the figure) [Note, this matrix is ​​read from top to bottom, from top to bottom Read from left to right].
In order to facilitate understanding and calculation, we can convert this matrix into a one-dimensional array, that is, B[0] = B[0][0] = B0, B[1] = B[0][1] = B1, B[2] = B[0][2] = B2 ... B[16] = B[3][3] = B15, then we use mathematical induction,
according to B[1] -> B[5 after shifting ], B[2] -> B[10], B[3]->B[15] Easy to get: B[i] = B[(4 * (i/4) + 5 * (i % 4)) mod 16] [i is the subscript] [combined with the picture is easier to understand]

The above is the algorithm of row shifting in encryption. After understanding this point, the reverse row shifting of decryption becomes simple.
Decryption is nothing more than changing the left shift to the right shift, that is, the first line does not move, the second line shifts one bit to the right, the third line shifts two bits to the right, and the fourth line shifts three bits to the right. As shown in the figure below,
insert image description here
it becomes
insert image description here
【Note, this matrix is ​​read from top to bottom and from left to right】.
In order to facilitate understanding and calculation, we can convert this matrix into a one-dimensional array, that is, B[0] = B[0][0] = B0, B[1] = B[0][1] = B1, B[2] = B[0][2] = B2 ... B[16] = B[3][3] = B15, then we can easily get
by mathematical induction: B[i] = B[(4 * (i/4) + 13 * (i % 4))mod 16] [i is the subscript] [combined with pictures for easier understanding]

inverse column obfuscation

Column obfuscation in the AES encryption algorithm
Use addition and multiplication of Galois field operations [For details on the Galois field, see the AES introduction article, the operations are all modulo operations] Calculate the product of the ciphertext matrix and the column confusion fixed matrix and then obtain the result matrix. The fixed matrix is ​​shown in the figure below:
insert image description here
for the convenience of calculation, the matrix can also be one-dimensionalized and then used for modulus operations. Here I adopt a relatively fast modulus operation scheme:
/**
* Algorithm explanation:
* Galois field multiplication defaults to modulo operation
* (110)2 * (11)2 => (x^2 + x ) * (x + 1) => x^3 + x^2 + x^2 + x => x^3 + x => (1010)2 * It can be understood as first shifting (110)2 to the left by one
bit Perform XOR operation with (110) to get => (1010)2
*/`
while (i < length of modulus 2) { result ^=(numb << (length of modulus 2 - i)); //Indicates the modulus 1 The value shifted to the left by n bits is stored in result and XORed with the previous value. See Algorithm Explanation for details. i self-increment } where numb is the value of the modulus 1. Afterwards, if the result of the matrix modulus operation exceeds 8 bits, it must be naturalized, that is, it will be XORed with the irreducible polynomial m(x)=x8+x4+x3+x+1 (0X11B)



After understanding the column obfuscation of the AES algorithm, the column obfuscation of AES decryption becomes simple. It only needs to modify the fixed matrix, as shown below: {"0E", "0B", "0D", "09"
} ,
{"09", "0E", "0B", "0D"},
{"0D", "09", "0E", "0B"},
{"0B", "0D", "09", "0E"}

reverse byte substitution

This is relatively simple. Just like encryption, the first 4 digits of the 8-digit ciphertext are used as the number of rows, and the last 4 digits are used as the number of columns to obtain the value in the reversed s box.

Invert the s-box:

/**
	 * 逆向s-盒
	 */
	public static final String[][] REVERSE_SBOX = {
    
    
			{
    
    "52","09","6A","D5","30","36","A5","38","BF","40","A3","9E","81","F3","D7","FB"},
			{
    
    "7C","E3","39","82","9B","2F","FF","87","34","8E","43","44","C4","DE","E9","CB"},
			{
    
    "54","7B","94","32","A6","C2","23","3D","EE","4C","95","0B","42","FA","C3","4E"},
			{
    
    "08","2E","A1","66","28","D9","24","B2","76","5B","A2","49","6D","8B","D1","25"},
			{
    
    "72","F8","F6","64","86","68","98","16","D4","A4","5C","CC","5D","65","B6","92"},
			{
    
    "6C","70","48","50","FD","ED","B9","DA","5E","15","46","57","A7","8D","9D","84"},
			{
    
    "90","D8","AB","00","8C","BC","D3","0A","F7","E4","58","05","B8","B3","45","06"},
			{
    
    "D0","2C","1E","8F","CA","3F","0F","02","C1","AF","BD","03","01","13","8A","6b"},
			{
    
    "3A","91","11","41","4F","67","DC","EA","97","F2","CF","CE","F0","B4","E6","73"},
			{
    
    "96","AC","74","22","E7","AD","35","85","E2","F9","37","E8","1C","75","DF","6E"},
			{
    
    "47","F1","1A","71","1D","29","C5","89","6F","B7","62","0E","AA","18","BE","1B"},
			{
    
    "FC","56","3E","4B","C6","D2","79","20","9A","DB","C0","FE","78","CD","5A","F4"},
			{
    
    "1F","DD","A8","33","88","07","C7","31","B1","12","10","59","27","80","EC","5F"},
			{
    
    "60","51","7F","A9","19","B5","4A","0D","2D","E5","7A","9F","93","C9","9C","EF"},
			{
    
    "A0","E0","3B","4D","AE","2A","F5","B0","C8","EB","BB","3C","83","53","99","61"},
			{
    
    "17","2B","04","7E","BA","77","D6","26","E1","69","14","63","55","21","0C","7d"}
	};

Design ideas

After mastering the decryption process and algorithm ideas, we can design the decryption.

  1. Firstly, the ciphertext grouping is realized through a decrypt method.
  2. Decryption of each group is achieved through the baseDecrypt method.
  3. Iterative decryption is realized through the decLoop method (write the round key addition, column confusion, row displacement, and byte substitution in it).
  4. Output plaintext.

The following is the official code:
see the article for details on the conversion of binary system:
Cryptography Extra Chapter on the Growth of Programmers ----- String (ascii) to Binary https://blog.csdn.net/qq_31236027/article/details /128579451

package aes;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import common.EncodeUtil;
import common.IEncrytion;
import common.EncodeUtil.EncodeRadix;
import constant.AESConstant;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * aes 加解密工具(无iv【偏移量】版)
 * @author zygswo
 *
 */
public class AesUtil implements IEncrytion{
    
    
	
	/**
	 * 密钥对象
	 */
	private KeyUtil subKeyObj = new KeyUtil().init(); 
	/**
	 * subkeys
	 */
	public List<String> subKeys = Collections.synchronizedList(new ArrayList<>());

	/**
	 * 分组加密(128位一组)
	 * @param text 明文
	 */
	@Override
	public String encrypt(String text) {
    
    
		StringBuilder sb = new StringBuilder();
		int textLen = text.length();
		//获取分组长度
		// DIV_LEN * CHAR_LEN = 128
		// 根据DIV_LEN进行分组,如CHAR_LEN=16位,那么就每8个字符一组
		int divLen = textLen % AESConstant.DIV_LEN == 0 ? textLen / AESConstant.DIV_LEN : (textLen / AESConstant.DIV_LEN + 1);
		//份组加密处理
		for (int i = 0; i < divLen; i++) {
    
    
			int startIndex = i * AESConstant.DIV_LEN;
			int endIndex = (startIndex + AESConstant.DIV_LEN) >= textLen ? textLen : (startIndex + AESConstant.DIV_LEN);
			String substr = text.substring(startIndex, endIndex);
			//尾部填充
			while(substr.length() < AESConstant.DIV_LEN) {
    
    
				substr += " ";
			}
			sb.append(baseEncrypt(substr));
		}
		return new BASE64Encoder().encode(sb.toString().toLowerCase().trim().getBytes());
	}
	
	/**
	 * 加密(每个密文都是128位)
	 * @param text 需要加密的文本
	 * @return
	 */
	private String baseEncrypt(String text) {
    
    
		//获取11组密钥
		if (subKeys == null || subKeys.isEmpty()) {
    
    
			subKeys = subKeyObj.generateKeys();
		}
		if (subKeys.size() != 11) {
    
    
			throw new IllegalArgumentException("密钥长度有误");
		}
		//转成16进制
		return EncodeUtil.binaryToHexStr(
				encloops(text, subKeys)
		).trim();
	}

	/**
	 * 10轮循环加密
	 * @param step1Result 初始置换后的结果
	 * @param subKeys 16组子密钥
	 * @return 循环加密结果
	 */
	private String encloops(String text, List<String> subKeys) {
    
    
		//转二进制
		String binTempStr = EncodeUtil.strtoBinary(text, AESConstant.CHAR_LEN);
		//1.初始化密钥加法层
//		System.out.println("binTempStr0 = " + binTempStr);
		binTempStr = xor(binTempStr, subKeys.get(0));
		//第一轮至第十轮
		for(int level = 1; level <= 10; level++) {
    
    
//			System.out.println("binTempStr1 = " + binTempStr);
			//2.字节代换层
			String[] temp = replace(binTempStr, AESConstant.SBOX);
			//3.扩撒层
			//3.1 行位移
			temp = shiftRow(temp);
			//3.2列混淆
			if (level < 10) {
    
    
				binTempStr = mixColumn(temp);
//				System.out.println("binTempStr3 = " + binTempStr);
			} else {
    
    
				binTempStr = "";
				for(String str:temp) {
    
    
					binTempStr += str;
				}
			}
//			System.out.println("binTempStr4 = " + binTempStr);
			//4.密钥加法层
			binTempStr = xor(binTempStr, subKeys.get(level));
//			System.out.println("binTempStr5 = " + binTempStr);
		}
//		System.out.println("binTempStr6 = " + binTempStr);
		return binTempStr;
	}
	
	/**
	 * 列混淆 【重点】
	 * @param _8bitArr 8位字符串数组 (2进制)
	 * @return 返回2进制字符串,方便后续的密钥加法
	 */
	private String mixColumn(String[] _8bitArr) {
    
    
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < _8bitArr.length; i+=4) {
    
    
			/**
			 * 注意:在列混淆中,每一位代表着x的指数,如(2)16=>(10)2 => x, (3)16=>(11)2 => x+1、 (25)16 => (0010 0101)2【采用十六进制】
			 * 使用矩阵乘积后的结果作为每一字节位上的结果,矩阵相乘用到了异或和或运算,异或模拟GF(2^8)域相乘,或模拟不同位相加
			 * 
			 * 如
			 * (01)16*(25)16=>		 x^5 	   + x^2 	 + 1
			 * (01)16*(25)16=> 		 x^5 	   + x^2	 + 1
			 * (02)16*(25)16=> x^6 		 + x^3 		 + x
			 * (03)16*(25)16=> x^6 + x^5 + x^3 + x^2 + x + 1
			 * +____________________________________________
			 * 				   		 x^5 	   + x^2 	 + 1
			 * 
			 * 注意如果度》8 要进行模约简
			 * 模约简方式,与不可约多项式m(x)=x8+x4+x3+x+1(十六进制表示为'11B')进行相加运算(异或)
			 */
			for (int j = 0; j < AESConstant.MIX_COLUMN_BOX.length; j++) {
    
    
				int res = 0;
				int rowNb = j;
				for (int m = 0; m < AESConstant.MIX_COLUMN_BOX[0].length; m++) {
    
    
					res ^= Integer.parseInt(
						EncodeUtil.binaryToDec(
								multiply(_8bitArr[i+j], AESConstant.MIX_COLUMN_BOX[rowNb][m])
						)	
					);
				}
				//超过了8位就和不可约多项式进行异或
				if (res >= 0x100) {
    
    
					res ^= 0x11B;  //11B => 不可约多项式m(x)=x8+x4+x3+x+1
				}
				//转二进制
				String finalRes = EncodeUtil.toBinary(res + "",EncodeRadix.DEC);
				//扩充
				while(finalRes.length() < 8) {
    
    
					finalRes = "0" + finalRes;
				}
				sb.append(finalRes);
			}
		}
		return sb.toString();
	}

	/**
	 * 二进制相乘
	 * @param source - 要处理的数(2进制)
	 * @param columnBox - 列混淆box(16进制)
	 * @return 相乘后结果(2进制)
	 */
	private String multiply(String source, String columnBox) {
    
    
		//将乘数十六进制转为二进制
		String temp = EncodeUtil.toBinary(columnBox, EncodeRadix.HEX);
		int result = 0;
		for (int i = 0; i < temp.length(); i++) {
    
    
			//如果开头位为0就跳过
			if (temp.charAt(i) == '0') {
    
    
				continue;
			}
			//否则就进行计算
			//转10进制
			int numb = Integer.parseInt(
				EncodeUtil.binaryToDec(source)
			);
			/**
			 * 算法解释:
			 * 伽罗瓦域乘法默认为模数运算
			 * (110)2 * (11)2 => (x^2 + x) * (x + 1) => x^3 + x^2 + x^2  + x => x^3 + x => (1010)2 
			 * 可以理解为先将(110)2左移一位后与(110)进行异或运算 得到 => (1010)2
			 */
			result ^=(numb << (temp.length()-1-i));
			/**
			 * 注意如果度》8 要进行模约简
			 * 模约简方式,与不可约多项式m(x)=x8+x4+x3+x+1(十六进制表示为'11B')进行相加运算(异或)
			 */
			if (result >= 0x100) {
    
    
				result ^= 0x11B;  //11B => 不可约多项式m(x)=x8+x4+x3+x+1
			}
		}
		return EncodeUtil.toBinary(result+"", EncodeRadix.DEC);
	}

	/**
	 * 行位移 
	 * @param _8bitArr 8位字符串数组【16进制】
	 * @return 按行输出(2进制)
	 */
	private String[] shiftRow(String[] _8bitArr) {
    
    
		String[] res = new String[_8bitArr.length];
		for(int i = 0; i < _8bitArr.length / 4;i++) {
    
    
			for (int j = 0; j < 4; j++) {
    
    
				int index = i*4 + j%4;
				//经过行位移后, 原来B0B1B2B3 -> B0B5B10B15, B4B5B6B7 -> B4B9B14B3 。。。 于是找到了这个规律
				res[index] = EncodeUtil.toBinary(
						_8bitArr[(4*i + 5*j)% _8bitArr.length], EncodeRadix.HEX
				); 
				//扩充
				while(res[index].length() < 8) {
    
    
					res[index]= "0" + res[index];
				}
			}
		}
		return res;
	}

	/**
	 * 字节代换层
	 * @param binStr 二进制流
	 * @param _128bitsStr 128位字符串
	 * @return 16进制数据
	 */
	private String[] replace(String _128bitsStr, String[][] sbox) {
    
    
		String[] result = new String[16];
		//分组计算
		for (int i = 0; i <result.length; i++) {
    
    
			String rowNb = EncodeUtil.binaryToDec(_128bitsStr.substring(i * 8, i * 8 + 4));
			String colNb = EncodeUtil.binaryToDec(_128bitsStr.substring(i * 8 + 4, i * 8 + 8));
			result[i] = sbox[Integer.parseInt(rowNb)][Integer.parseInt(colNb)];
		}
		return result;
	}

	/**
	 * 异或运算
	 * @param text1 text1 
	 * @param text2 text2
	 * @return
	 */
	private String xor(String text1, String text2) {
    
    
		if (text1 == null || text2 == null || text1.length() != text2.length()) {
    
    
			throw new IllegalArgumentException("异或运算失败");
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < text1.length();i++) {
    
    
			char ch1 = text1.charAt(i);
			char ch2 = text2.charAt(i);
			sb.append((ch1) ^ (ch2));
		}
		return sb.toString().trim();
	}


	/**
	 * 分组解密
	 * @param encrytedText 密文
	 */
	@Override
	public String decrypt(String encrytedText) {
    
    
		try {
    
    
			//base64解码
			byte[] bytes = new BASE64Decoder().decodeBuffer(encrytedText);
			String str = new String(bytes,Charset.forName("UTF8"));
			int textLen = str.length();
			StringBuilder sb = new StringBuilder();
			int divLen = textLen < 32 ? 1 : (int)(Math.ceil(textLen/(4*8*1.0))); //因为加密后会自动填充所以长度必为字符长度的倍数(HEX 4位)
			//分组解密
			for (int i = 0; i< divLen; i++) {
    
    
				int startIndex = i * (4*8);
				int endIndex = (startIndex + (4*8));
				String temp = str.substring(startIndex, endIndex);
				sb.append(baseDecrypt(temp));
			}
			return sb.toString();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 解密
	 * @param encHexStr 加密16进制文本
	 * @return
	 */
	private String baseDecrypt(String encHexStr) {
    
    
		//1. 获取密钥
		if (subKeys == null || subKeys.isEmpty()) {
    
    
			throw new IllegalArgumentException("密钥获取失败");
		}
		if (subKeys.size() != 11) {
    
    
			throw new IllegalArgumentException("密钥长度有误");
		}
		//2. 讲16进制转二进制并迭代解密输出结果
		return EncodeUtil.binaryToStr(
				decLoop(encHexStr,subKeys),
				AESConstant.CHAR_LEN
		);
	}
	
	/**
	 * 迭代递归解密
	 * @param encHexStr 加密16进制文本
	 * @param subKeys 子密钥
	 * @return 解密结果
	 */
	private String decLoop(String encHexStr, List<String> subKeys) {
    
    
		//1.16进制转二进制
		String binTempStr = EncodeUtil.toBinary(
				encHexStr, EncodeRadix.HEX);
		//2.逆向迭代解密
		for (int level=10;level > 0;level--) {
    
    
			//密钥加法层
//			System.out.println("reverseReplace binTempStr1 = " + binTempStr);
			binTempStr = xor(binTempStr, subKeys.get(level)); //没问题
//			System.out.println("reverseReplace binTempStr2 = " + binTempStr);
			String[] temp = new String[AESConstant.ARR_LEN];
			//转成字符串数组
			int len = 8; //字节数组
			for (int i = 0; i < AESConstant.ARR_LEN; i++) {
    
    
				temp[i] = binTempStr.substring(i* len, (i+1)*len);
			}
			//逆向列混淆层
			if (level < 10) {
    
    
				binTempStr = reverseMixColumn(temp);
//				System.out.println("reverseReplace binTempStr3 = " + binTempStr);
				for (int i = 0; i < AESConstant.ARR_LEN; i++) {
    
    
					temp[i] = binTempStr.substring(i* len, (i+1)*len);
				}
			}
			//逆向行位移层
			binTempStr = reverseShiftRow(temp);
//			System.out.println("reverseReplace binTempStr4 = " + binTempStr);
			//逆向字节代换
			binTempStr = reverseReplace(binTempStr, AESConstant.REVERSE_SBOX);
//			System.out.println("reverseReplace binTempStr5 = " + binTempStr);
		}
		//密钥加法层
//		System.out.println("reverseReplace binTempStr6 = " + binTempStr);
		binTempStr = xor(binTempStr, subKeys.get(0));
//		System.out.println("reverseReplace binTempStr7 = " + binTempStr);
		return binTempStr;
	}
	
	/**
	 * 逆向字节代换层
	 * @param binStr 二进制流
	 * @param _128bitsStr 128位字符串
	 * @return 2进制进制数据
	 */
	private String reverseReplace(String _128bitsStr, String[][] sbox) {
    
    
		StringBuilder result = new StringBuilder();
		//分组计算
		for (int i = 0; i < AESConstant.ARR_LEN; i++) {
    
    
			String rowNb = EncodeUtil.binaryToDec(_128bitsStr.substring(i * 8, i * 8 + 4));
			String colNb = EncodeUtil.binaryToDec(_128bitsStr.substring(i * 8 + 4, i * 8 + 8));
			result.append(EncodeUtil.toBinary(sbox[Integer.parseInt(rowNb)][Integer.parseInt(colNb)], EncodeRadix.HEX));
		}
		return result.toString();
	}
	
	/**
	 * 逆向行位移 
	 * @param _8bitArr 字符串数组(16位)【2进制】
	 * @return 按行输出(2进制)
	 */
	private String reverseShiftRow(String[] _8bitArr) {
    
    
		StringBuilder res = new StringBuilder();
		for(int i = 0; i < _8bitArr.length / 4;i++) {
    
    
			for (int j = 0; j < 4; j++) {
    
    
				//经过逆向行位移后, 原来B0B1B2B3 -> B0B13B10B7, B4B5B6B7 -> B4B1B14B11 。。。 于是找到了这个规律
				String temp =_8bitArr[(4*i + 13*j)% _8bitArr.length];
				//扩充
				while(temp.length() < 8) {
    
    
					temp = "0" + temp;
				}
				res.append(temp);
			}
		}
		return res.toString();
	}
	
	/**
	 * 列混淆 【重点】
	 * @param _8bitArr 8位字符串数组 (2进制)
	 * @return 返回2进制字符串,方便后续的密钥加法
	 */
	private String reverseMixColumn(String[] _8bitArr) {
    
    
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < _8bitArr.length; i+=4) {
    
    
			/**
			 * 注意:在列混淆中,每一位代表着x的指数,如(2)16=>(10)2 => x, (3)16=>(11)2 => x+1、 (25)16 => (0010 0101)2【采用十六进制】
			 * 使用矩阵乘积后的结果作为每一字节位上的结果,矩阵相乘用到了异或和或运算,异或模拟GF(2^8)域相乘,或模拟不同位相加
			 * 
			 * 如
			 * (01)16*(25)16=>		 x^5 	   + x^2 	 + 1
			 * (01)16*(25)16=> 		 x^5 	   + x^2	 + 1
			 * (02)16*(25)16=> x^6 		 + x^3 		 + x
			 * (03)16*(25)16=> x^6 + x^5 + x^3 + x^2 + x + 1
			 * +____________________________________________
			 * 				   		 x^5 	   + x^2 	 + 1
			 * 
			 * 注意如果度》8 要进行模约简
			 * 模约简方式,与不可约多项式m(x)=x8+x4+x3+x+1(十六进制表示为'11B')进行相加运算(异或)
			 */
			for (int j = 0; j < AESConstant.REVERSE_MIX_COLUMN_BOX.length; j++) {
    
    
				int res = 0;
				int rowNb = j;
				int initLen = _8bitArr[i+j].length();
				for (int m = 0; m < AESConstant.REVERSE_MIX_COLUMN_BOX[0].length; m++) {
    
    
					res ^= Integer.parseInt(
						EncodeUtil.binaryToDec(
								multiply(_8bitArr[i+j], AESConstant.REVERSE_MIX_COLUMN_BOX[rowNb][m])
						)	
					);
				}
				//超过了8位就和不可约多项式进行异或
				if (res >= 0x100) {
    
    
					res ^= 0x11B;  //11B => 不可约多项式m(x)=x8+x4+x3+x+1
				}
				//转二进制
				String finalRes = EncodeUtil.toBinary(res + "",EncodeRadix.DEC);
				//扩充
				while(finalRes.length() < initLen) {
    
    
					finalRes = "0" + finalRes;
				}
				sb.append(finalRes);
			}
		}
		return sb.toString();
	}

	public static void main(String[] args) {
    
    
		AesUtil util = new AesUtil();
		String encrytedStr = util.encrypt("{\"code\":200,\"message\":\"成功!\",\"data\":{\"id\":\"2103813902831\",\"name\":\"章鱼哥是我哦\"}}");
		System.out.println("encrytedStr = " + encrytedStr);
		System.out.println("result= " + util.decrypt(encrytedStr));
	}
}

Running Results
insert image description here
—————————————————————————————————————————————————————————————————————————————

Guess you like

Origin blog.csdn.net/qq_31236027/article/details/131206018