Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.gdface.utils.encrypt.AES128ECBNoPadding Maven / Gradle / Ivy
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());
}
}