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

net.gdface.utils.encrypt.AES128ECBNoPadding Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package net.gdface.utils.encrypt;

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

import net.gdface.utils.Base64Utils;

import static net.gdface.utils.ConditionChecks.checkNotNull;
import static net.gdface.utils.ConditionChecks.checkArgument;

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

public class AES128ECBNoPadding {
	private static final Charset UTF_8 = Charset.forName("UTF-8");
	/**
     * 加密
     * @param sSrc 输入数据,长度必须是16的倍数
     * @param sKey key,长度必须是16,24,32
     * @return 加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] sSrc, byte[] sKey) throws Exception {
    	checkArgument(null != sSrc,"sSrc is null");
        checkArgument(null != sKey,"sKey is null");
        // 判断Key是否为16位
        checkArgument(sKey.length == 16,"length of sKey must be 16 bytes");
        SecretKeySpec skeySpec = new SecretKeySpec(sKey, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        return cipher.doFinal(sSrc);
    }
    /**
     * 加密
     * @param sSrc 输入数据,长度必须是16的倍数
     * @param sKey key,长度必须是16,24,32
     * @return 加密数据(base64)
     * @throws Exception
     */
    public static String encrypt(String sSrc, String sKey) throws Exception {
        byte[] encrypted = encrypt(
        		checkNotNull(sSrc,"sSrc is null").getBytes(UTF_8),
    			checkNotNull(sKey,"sKey is null").getBytes(UTF_8));
        return Base64Utils.encode(encrypted);
    }
    /**
     * 解密
     * @param sSrc 输入加密数据
     * @param sKey key
     * @return 解密数据
     * @throws Exception
     */
    public  static byte[] decrypt(byte[] sSrc, byte[] sKey) throws Exception {
    	checkArgument(null != sSrc,"sSrc is null");
    	checkArgument(null != sKey,"sKey is null");
    	// 判断Key是否为16位
    	checkArgument(sKey.length == 16,"length of sKey must be 16 bytes");
    	SecretKeySpec skeySpec = new SecretKeySpec(sKey, "AES");
    	Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    	cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		return cipher.doFinal(sSrc);
    }
    /**
     * 解密
     * @param sSrc 输入加密数据(base64)
     * @param sKey key
     * @return 解密数据(base64)
     * @throws Exception
     */
    public static String decrypt(String sSrc, String sKey) throws Exception {
    	// sSrc为base64字符串,先用base64解密
    	byte[] decoded = decrypt(Base64Utils.decode(checkNotNull(sSrc,"sSrc is null")),
    			checkNotNull(sKey,"sKey is null").getBytes(UTF_8));
    	return new String(decoded,UTF_8);
    }
 
    /**
	 * 自动补全加密
* 自动在加密数据前加4个字节保存数据长度,对数据长度自动补全到16倍数, * 自动补全密钥到16,24,32字节,超过32字节的密钥抛出异常 * @param sSrc 输入数据, * @param sKey key * @return 加密数据 * @throws Exception */ public static byte[] wrapEncrypt(byte[] sSrc, byte[] sKey) throws Exception { checkArgument(null != sSrc,"sSrc is null"); checkArgument(null != sKey,"sKey is null"); checkArgument(sKey.length <= 32 ,"too long sKey"); byte[] paddingKey = sKey; byte[] paddingSrc = new byte[sSrc.length + 4]; // 数据头部添加4字节保存sSrc.length(小端) paddingSrc[0] = (byte) (sSrc.length); paddingSrc[1] = (byte) (sSrc.length>>8); paddingSrc[2] = (byte) (sSrc.length>>16); paddingSrc[3] = (byte) (sSrc.length>>24); System.arraycopy(sSrc, 0, paddingSrc, 4, sSrc.length); if(paddingSrc.length %16 != 0){ // 填充到16的倍数 paddingSrc = Arrays.copyOf(paddingSrc, (paddingSrc.length + 16 -1 )/16*16); } if(sKey.length%8 != 0){ // 填充到16,24,32字节 int padSize = Math.max(16, (sKey.length + 8 -1 )/8*8); paddingKey = Arrays.copyOf(sKey, padSize); } return encrypt(paddingSrc,paddingKey); } /** * 自动补全加密
* 自动在加密数据前加4个字节保存数据长度,对数据长度自动补全到16倍数, * 自动补全密钥到16,24,32字节,超过32字节的密钥抛出异常 * @param sSrc 输入数据 * @param sKey key * @return 加密数据(base64) * @throws Exception */ public static String wrapEncrypt(String sSrc, String sKey) throws Exception { byte[] encrypted = wrapEncrypt( checkNotNull(sSrc,"sSrc is null").getBytes(UTF_8), checkNotNull(sKey,"sKey is null").getBytes(UTF_8)); return Base64Utils.encode(encrypted); } /** * 解密{@link #wrapEncrypt(byte[], byte[])}加密的数据 * @param sSrc 输入加密数据 * @param sKey key 自动补全密钥到16,24,32字节,超过32字节的密钥抛出异常 * @return 解密数据 * @throws Exception */ public static byte[] wrapDecrypt(byte[] sSrc, byte[] sKey) throws Exception { checkArgument(null != sSrc,"sSrc is null"); checkArgument(null != sKey,"sKey is null"); checkArgument(sKey.length <= 32 ,"too long sKey"); byte[] paddingKey = sKey; if(sKey.length%8 != 0){ // 填充到16,24,32字节 int padSize = Math.max(16, (sKey.length + 8 -1 )/8*8); paddingKey = Arrays.copyOf(sKey, padSize); } byte[] wrap = decrypt(sSrc, paddingKey); // 数据头部添加4字节保存sSrc.length(小端) int wrapLength= ((int)wrap[0] & 0X000000FF) | (((int) (wrap[1] << 8)) & 0X0000FF00) | (((int) (wrap[2] << 16)) & 0X00FF0000) | (((int) (wrap[3] << 24)) & 0XFF000000); checkArgument(wrapLength >0 && wrapLength < wrap.length,"INVALID wrap length %s",wrapLength); byte[] data = new byte[wrapLength]; System.arraycopy(wrap, 4, data, 0, wrapLength); return data; } /** * 解密{@link #wrapEncrypt(String, String)}加密的数据 * @param sSrc 输入加密数据(base64) * @param sKey key * @return 解密数据(base64) * @throws Exception */ public static String wrapDecrypt(String sSrc, String sKey) throws Exception { // sSrc为base64字符串,先用base64解密 byte[] decoded = wrapDecrypt(Base64Utils.decode(checkNotNull(sSrc,"sSrc is null")), checkNotNull(sKey,"sKey is null").getBytes(UTF_8)); return new String(decoded,UTF_8); } public static void main(String[] args) throws Exception { //此处使用AES-128-ECB加密模式,key需要为16位。 String cKey = "WllNRVNTQUdFOTk@"; // 需要加密的字串 String cSrc = "@FACE@Android@2@[email protected]@05352CF3086932E2@@ "; System.out.println("待加密的字串是:" + cSrc); // 加密 String enString = AES128ECBNoPadding.encrypt(cSrc, cKey); System.out.println("加密后的字串是:" + enString); // 解密 String DeString = AES128ECBNoPadding.decrypt(enString, cKey); System.out.println("解密后的字串是:" + DeString); System.out.println("/////////////////// WRAP TEST////////////////////////"); String cKey2 = "WllNRVNTQUdFOTk"; // 需要加密的字串 String cSrc2 = "{\"channel\":\"1610176971640\",\"qrCodeSceneId\":\"16169887538401\",\"IDcardSceneId\":\"16169887538402\",\"publicKey\":\"04A866F61DA13F8FA893A5C44D131D051FECBAE2C2F045978A17C815E7B1DE108519F5D5A7DE7D17A42BD407BA6503CEFB4C18E1940FEF9153047F3798B8A8C87D\",\"privateKey\":\"00B69D059FDC1B65E41608A5CA72A527FBB2FBC67ECA87999B3F56E65BC46610EE\",\"position\":\"江苏省,南京市,鼓楼区\",\"verifierDept\":\"XXX医院\",\"verifierName\":\"XXX\",\"verifierPhone\":\"18888888888\",\"location\":\"32.0238、118.4643\"}"; System.out.println("待加密的字串是:" + cSrc2 + " 长度:" + cSrc2.length()); // 加密 String enString2 = AES128ECBNoPadding.wrapEncrypt(cSrc2, cKey2); System.out.println("加密后的字串是:" + enString2); // 解密 String deString2= AES128ECBNoPadding.wrapDecrypt(enString2, cKey2); System.out.println("解密后的字串是:" + deString2 + " 长度:" + deString2.length()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy