All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jfinal.kit.AesKit Maven / Gradle / Ivy

package com.jfinal.kit;

import java.nio.charset.Charset;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * 完全兼容微信所使用的AES加密方式。
 * aes的key必须是256byte长(比如32个字符),可以使用AesKit.genAesKey()来生成一组key
 * @ClassName: AesKit  
 */
public class AesKit {
	
	private static final Charset UTF_8 = Charset.forName("UTF-8");
	
	private AesKit(){}
	
	public static String genAesKey(){
		return HashKit.generateSalt(32);
	}
	
	public static byte[] encrypt(byte[] content, String aesTextKey) {
		return encrypt(content, aesTextKey.getBytes(UTF_8));
	}
	
	public static byte[] encrypt(String content, String aesTextKey) {
		return encrypt(content.getBytes(UTF_8), aesTextKey.getBytes(UTF_8));
	}
	
	public static byte[] encrypt(String content, String charsetName, String aesTextKey){
		return encrypt(content.getBytes(Charset.forName(charsetName)), aesTextKey.getBytes(UTF_8));
	}
	
	public static byte[] decrypt(byte[] content, String aesTextKey) {
		return decrypt(content, aesTextKey.getBytes(UTF_8));
	}
	
	public static String decryptToStr(byte[] content, String aesTextKey) {
		return new String(decrypt(content, aesTextKey.getBytes(UTF_8)), UTF_8);
	}
	
	public static String decryptToStr(byte[] content, String aesTextKey, String charsetName) {
		return new String(decrypt(content, aesTextKey.getBytes(UTF_8)), Charset.forName(charsetName));
	}
	
	public static byte[] encrypt(byte[] content, byte[] aesKey){
		try {
			if(aesKey.length != 32){
				throw new RuntimeException("IllegalAesKey, aesKey's length must be 32");
			}
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return cipher.doFinal(PKCS7Encoder.encode(content));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(),e);
		}
	}

	public static byte[] decrypt(byte[] encrypted, byte[] aesKey){
		try {
			if(aesKey.length != 32){
				throw new RuntimeException("IllegalAesKey, aesKey's length must be 32");
			}
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
            cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
            return PKCS7Encoder.decode(cipher.doFinal(encrypted));
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(),e);
		}
	}
	/**
	 * 提供基于PKCS7算法的加解密接口.
	 */
	static class PKCS7Encoder {
	    static int BLOCK_SIZE = 32;
	    
	    static byte[] encode(byte[] src) {
	    	int count = src.length;
	        // 计算需要填充的位数
	        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
	        if (amountToPad == 0) {
	            amountToPad = BLOCK_SIZE;
	        }
	        // 获得补位所用的字符
	        byte pad = (byte) (amountToPad & 0xFF);
	        byte[] pads = new byte[amountToPad];
	        for (int index = 0; index < amountToPad; index++) {
	        	pads[index] = pad;
	        }
	        int length = count + amountToPad;
	        byte[] dest = new byte[length];
	        System.arraycopy(src, 0, dest, 0, count);
	        System.arraycopy(pads, 0, dest, count, amountToPad);
	        return dest;
	    }

	    static byte[] decode(byte[] decrypted) {
	        int pad = (int) decrypted[decrypted.length - 1];
	        if (pad < 1 || pad > 32) {
	            pad = 0;
	        }
	        if(pad > 0){
	        	return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
	        }
	        return decrypted;
	    }
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy