|
|
|
|
import android.util.Base64; |
|
|
|
import java.io.File; |
|
import java.io.FileInputStream; |
|
import java.io.IOException; |
|
import java.security.DigestInputStream; |
|
import java.security.InvalidKeyException; |
|
import java.security.MessageDigest; |
|
import java.security.NoSuchAlgorithmException; |
|
import java.security.SecureRandom; |
|
|
|
import javax.crypto.Cipher; |
|
import javax.crypto.Mac; |
|
import javax.crypto.spec.SecretKeySpec; |
|
|
|
/**
|
|
* <pre>
|
|
* author: Blankj
|
|
* blog : http://blankj.com
|
|
* time : 2016/8/2
|
|
* desc : 加密解密相关的工具类
|
|
* </pre>
|
|
*/
|
|
public final class EncryptUtils {
|
|
|
|
private EncryptUtils() {
|
|
throw new UnsupportedOperationException("u can't instantiate me..."); |
|
} |
|
|
|
/*********************** 哈希加密相关 ***********************/
|
|
/**
|
|
* MD2加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptMD2ToString(String data) {
|
|
return encryptMD2ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* MD2加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptMD2ToString(byte[] data) {
|
|
return bytes2HexString(encryptMD2(data)); |
|
} |
|
|
|
/**
|
|
* MD2加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptMD2(byte[] data) {
|
|
return hashTemplate(data, "MD2"); |
|
} |
|
|
|
/**
|
|
* MD5加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptMD5ToString(String data) {
|
|
return encryptMD5ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* MD5加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param salt 盐
|
|
* @return 16进制加盐密文
|
|
*/
|
|
public static String encryptMD5ToString(String data, String salt) {
|
|
return bytes2HexString(encryptMD5((data + salt).getBytes())); |
|
} |
|
|
|
/**
|
|
* MD5加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptMD5ToString(byte[] data) {
|
|
return bytes2HexString(encryptMD5(data)); |
|
} |
|
|
|
/**
|
|
* MD5加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param salt 盐字节数组
|
|
* @return 16进制加盐密文
|
|
*/
|
|
public static String encryptMD5ToString(byte[] data, byte[] salt) {
|
|
if (data == null || salt == null) return null; |
|
byte[] dataSalt = new byte[data.length + salt.length]; |
|
System.arraycopy(data, 0, dataSalt, 0, data.length); |
|
System.arraycopy(salt, 0, dataSalt, data.length, salt.length); |
|
return bytes2HexString(encryptMD5(dataSalt)); |
|
} |
|
|
|
/**
|
|
* MD5加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptMD5(byte[] data) {
|
|
return hashTemplate(data, "MD5"); |
|
} |
|
|
|
/**
|
|
* MD5加密文件
|
|
*
|
|
* @param filePath 文件路径
|
|
* @return 文件的16进制密文
|
|
*/
|
|
public static String encryptMD5File2String(String filePath) {
|
|
File file = isSpace(filePath) ? null : new File(filePath); |
|
return encryptMD5File2String(file); |
|
} |
|
|
|
/**
|
|
* MD5加密文件
|
|
*
|
|
* @param filePath 文件路径
|
|
* @return 文件的MD5校验码
|
|
*/
|
|
public static byte[] encryptMD5File(String filePath) {
|
|
File file = isSpace(filePath) ? null : new File(filePath); |
|
return encryptMD5File(file); |
|
} |
|
|
|
/**
|
|
* MD5加密文件
|
|
*
|
|
* @param file 文件
|
|
* @return 文件的16进制密文
|
|
*/
|
|
public static String encryptMD5File2String(File file) {
|
|
return bytes2HexString(encryptMD5File(file)); |
|
} |
|
|
|
/**
|
|
* MD5加密文件
|
|
*
|
|
* @param file 文件
|
|
* @return 文件的MD5校验码
|
|
*/
|
|
public static byte[] encryptMD5File(File file) {
|
|
if (file == null) return null; |
|
FileInputStream fis = null; |
|
DigestInputStream digestInputStream; |
|
try {
|
|
fis = new FileInputStream(file); |
|
MessageDigest md = MessageDigest.getInstance("MD5"); |
|
digestInputStream = new DigestInputStream(fis, md); |
|
byte[] buffer = new byte[256 * 1024]; |
|
while (digestInputStream.read(buffer) > 0) ; |
|
md = digestInputStream.getMessageDigest(); |
|
return md.digest(); |
|
} catch (NoSuchAlgorithmException | IOException e) {
|
|
e.printStackTrace(); |
|
return null; |
|
} finally {
|
|
CloseUtils.closeIO(fis); |
|
} |
|
} |
|
|
|
/**
|
|
* SHA1加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA1ToString(String data) {
|
|
return encryptSHA1ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* SHA1加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA1ToString(byte[] data) {
|
|
return bytes2HexString(encryptSHA1(data)); |
|
} |
|
|
|
/**
|
|
* SHA1加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptSHA1(byte[] data) {
|
|
return hashTemplate(data, "SHA1"); |
|
} |
|
|
|
/**
|
|
* SHA224加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA224ToString(String data) {
|
|
return encryptSHA224ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* SHA224加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA224ToString(byte[] data) {
|
|
return bytes2HexString(encryptSHA224(data)); |
|
} |
|
|
|
/**
|
|
* SHA224加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptSHA224(byte[] data) {
|
|
return hashTemplate(data, "SHA224"); |
|
} |
|
|
|
/**
|
|
* SHA256加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA256ToString(String data) {
|
|
return encryptSHA256ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* SHA256加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA256ToString(byte[] data) {
|
|
return bytes2HexString(encryptSHA256(data)); |
|
} |
|
|
|
/**
|
|
* SHA256加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptSHA256(byte[] data) {
|
|
return hashTemplate(data, "SHA256"); |
|
} |
|
|
|
/**
|
|
* SHA384加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA384ToString(String data) {
|
|
return encryptSHA384ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* SHA384加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA384ToString(byte[] data) {
|
|
return bytes2HexString(encryptSHA384(data)); |
|
} |
|
|
|
/**
|
|
* SHA384加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptSHA384(byte[] data) {
|
|
return hashTemplate(data, "SHA384"); |
|
} |
|
|
|
/**
|
|
* SHA512加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA512ToString(String data) {
|
|
return encryptSHA512ToString(data.getBytes()); |
|
} |
|
|
|
/**
|
|
* SHA512加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptSHA512ToString(byte[] data) {
|
|
return bytes2HexString(encryptSHA512(data)); |
|
} |
|
|
|
/**
|
|
* SHA512加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptSHA512(byte[] data) {
|
|
return hashTemplate(data, "SHA512"); |
|
} |
|
|
|
/**
|
|
* hash加密模板
|
|
*
|
|
* @param data 数据
|
|
* @param algorithm 加密算法
|
|
* @return 密文字节数组
|
|
*/
|
|
private static byte[] hashTemplate(byte[] data, String algorithm) {
|
|
if (data == null || data.length <= 0) return null; |
|
try {
|
|
MessageDigest md = MessageDigest.getInstance(algorithm); |
|
md.update(data); |
|
return md.digest(); |
|
} catch (NoSuchAlgorithmException e) {
|
|
e.printStackTrace(); |
|
return null; |
|
} |
|
} |
|
|
|
/**
|
|
* HmacMD5加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacMD5ToString(String data, String key) {
|
|
return encryptHmacMD5ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacMD5加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacMD5ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacMD5(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacMD5加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacMD5(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacMD5"); |
|
} |
|
|
|
/**
|
|
* HmacSHA1加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA1ToString(String data, String key) {
|
|
return encryptHmacSHA1ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacSHA1加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA1ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacSHA1(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacSHA1加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacSHA1(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacSHA1"); |
|
} |
|
|
|
/**
|
|
* HmacSHA224加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA224ToString(String data, String key) {
|
|
return encryptHmacSHA224ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacSHA224加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA224ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacSHA224(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacSHA224加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacSHA224(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacSHA224"); |
|
} |
|
|
|
/**
|
|
* HmacSHA256加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA256ToString(String data, String key) {
|
|
return encryptHmacSHA256ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacSHA256加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA256ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacSHA256(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacSHA256加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacSHA256(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacSHA256"); |
|
} |
|
|
|
/**
|
|
* HmacSHA384加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA384ToString(String data, String key) {
|
|
return encryptHmacSHA384ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacSHA384加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA384ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacSHA384(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacSHA384加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacSHA384(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacSHA384"); |
|
} |
|
|
|
/**
|
|
* HmacSHA512加密
|
|
*
|
|
* @param data 明文字符串
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA512ToString(String data, String key) {
|
|
return encryptHmacSHA512ToString(data.getBytes(), key.getBytes()); |
|
} |
|
|
|
/**
|
|
* HmacSHA512加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptHmacSHA512ToString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptHmacSHA512(data, key)); |
|
} |
|
|
|
/**
|
|
* HmacSHA512加密
|
|
*
|
|
* @param data 明文字节数组
|
|
* @param key 秘钥
|
|
* @return 密文字节数组
|
|
*/
|
|
public static byte[] encryptHmacSHA512(byte[] data, byte[] key) {
|
|
return hmacTemplate(data, key, "HmacSHA512"); |
|
} |
|
|
|
/**
|
|
* Hmac加密模板
|
|
*
|
|
* @param data 数据
|
|
* @param key 秘钥
|
|
* @param algorithm 加密算法
|
|
* @return 密文字节数组
|
|
*/
|
|
private static byte[] hmacTemplate(byte[] data, byte[] key, String algorithm) {
|
|
if (data == null || data.length == 0 || key == null || key.length == 0) return null; |
|
try {
|
|
SecretKeySpec secretKey = new SecretKeySpec(key, algorithm); |
|
Mac mac = Mac.getInstance(algorithm); |
|
mac.init(secretKey); |
|
return mac.doFinal(data); |
|
} catch (InvalidKeyException | NoSuchAlgorithmException e) {
|
|
e.printStackTrace(); |
|
return null; |
|
} |
|
} |
|
|
|
/************************ DES加密相关 ***********************/
|
|
/**
|
|
* DES转变
|
|
* <p>法算法名称/加密模式/填充方式</p>
|
|
* <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
|
|
* <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
|
|
*/
|
|
public static String DES_Transformation = "DES/ECB/NoPadding"; |
|
private static final String DES_Algorithm = "DES"; |
|
|
|
/**
|
|
* DES加密后转为Base64编码
|
|
*
|
|
* @param data 明文
|
|
* @param key 8字节秘钥
|
|
* @return Base64密文
|
|
*/
|
|
public static byte[] encryptDES2Base64(byte[] data, byte[] key) {
|
|
return base64Encode(encryptDES(data, key)); |
|
} |
|
|
|
/**
|
|
* DES加密后转为16进制
|
|
*
|
|
* @param data 明文
|
|
* @param key 8字节秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptDES2HexString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptDES(data, key)); |
|
} |
|
|
|
/**
|
|
* DES加密
|
|
*
|
|
* @param data 明文
|
|
* @param key 8字节秘钥
|
|
* @return 密文
|
|
*/
|
|
public static byte[] encryptDES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, DES_Algorithm, DES_Transformation, true); |
|
} |
|
|
|
/**
|
|
* DES解密Base64编码密文
|
|
*
|
|
* @param data Base64编码密文
|
|
* @param key 8字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptBase64DES(byte[] data, byte[] key) {
|
|
return decryptDES(base64Decode(data), key); |
|
} |
|
|
|
/**
|
|
* DES解密16进制密文
|
|
*
|
|
* @param data 16进制密文
|
|
* @param key 8字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptHexStringDES(String data, byte[] key) {
|
|
return decryptDES(hexString2Bytes(data), key); |
|
} |
|
|
|
/**
|
|
* DES解密
|
|
*
|
|
* @param data 密文
|
|
* @param key 8字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptDES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, DES_Algorithm, DES_Transformation, false); |
|
} |
|
|
|
/************************ 3DES加密相关 ***********************/
|
|
/**
|
|
* 3DES转变
|
|
* <p>法算法名称/加密模式/填充方式</p>
|
|
* <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
|
|
* <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
|
|
*/
|
|
public static String TripleDES_Transformation = "DESede/ECB/NoPadding"; |
|
private static final String TripleDES_Algorithm = "DESede"; |
|
|
|
|
|
/**
|
|
* 3DES加密后转为Base64编码
|
|
*
|
|
* @param data 明文
|
|
* @param key 24字节秘钥
|
|
* @return Base64密文
|
|
*/
|
|
public static byte[] encrypt3DES2Base64(byte[] data, byte[] key) {
|
|
return base64Encode(encrypt3DES(data, key)); |
|
} |
|
|
|
/**
|
|
* 3DES加密后转为16进制
|
|
*
|
|
* @param data 明文
|
|
* @param key 24字节秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encrypt3DES2HexString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encrypt3DES(data, key)); |
|
} |
|
|
|
/**
|
|
* 3DES加密
|
|
*
|
|
* @param data 明文
|
|
* @param key 24字节密钥
|
|
* @return 密文
|
|
*/
|
|
public static byte[] encrypt3DES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, true); |
|
} |
|
|
|
/**
|
|
* 3DES解密Base64编码密文
|
|
*
|
|
* @param data Base64编码密文
|
|
* @param key 24字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptBase64_3DES(byte[] data, byte[] key) {
|
|
return decrypt3DES(base64Decode(data), key); |
|
} |
|
|
|
/**
|
|
* 3DES解密16进制密文
|
|
*
|
|
* @param data 16进制密文
|
|
* @param key 24字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptHexString3DES(String data, byte[] key) {
|
|
return decrypt3DES(hexString2Bytes(data), key); |
|
} |
|
|
|
/**
|
|
* 3DES解密
|
|
*
|
|
* @param data 密文
|
|
* @param key 24字节密钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decrypt3DES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, false); |
|
} |
|
|
|
/************************ AES加密相关 ***********************/
|
|
/**
|
|
* AES转变
|
|
* <p>法算法名称/加密模式/填充方式</p>
|
|
* <p>加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB</p>
|
|
* <p>填充方式有:NoPadding、ZerosPadding、PKCS5Padding</p>
|
|
*/
|
|
public static String AES_Transformation = "AES/ECB/NoPadding"; |
|
private static final String AES_Algorithm = "AES"; |
|
|
|
|
|
/**
|
|
* AES加密后转为Base64编码
|
|
*
|
|
* @param data 明文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return Base64密文
|
|
*/
|
|
public static byte[] encryptAES2Base64(byte[] data, byte[] key) {
|
|
return base64Encode(encryptAES(data, key)); |
|
} |
|
|
|
/**
|
|
* AES加密后转为16进制
|
|
*
|
|
* @param data 明文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return 16进制密文
|
|
*/
|
|
public static String encryptAES2HexString(byte[] data, byte[] key) {
|
|
return bytes2HexString(encryptAES(data, key)); |
|
} |
|
|
|
/**
|
|
* AES加密
|
|
*
|
|
* @param data 明文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return 密文
|
|
*/
|
|
public static byte[] encryptAES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, AES_Algorithm, AES_Transformation, true); |
|
} |
|
|
|
/**
|
|
* AES解密Base64编码密文
|
|
*
|
|
* @param data Base64编码密文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptBase64AES(byte[] data, byte[] key) {
|
|
return decryptAES(base64Decode(data), key); |
|
} |
|
|
|
/**
|
|
* AES解密16进制密文
|
|
*
|
|
* @param data 16进制密文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptHexStringAES(String data, byte[] key) {
|
|
return decryptAES(hexString2Bytes(data), key); |
|
} |
|
|
|
/**
|
|
* AES解密
|
|
*
|
|
* @param data 密文
|
|
* @param key 16、24、32字节秘钥
|
|
* @return 明文
|
|
*/
|
|
public static byte[] decryptAES(byte[] data, byte[] key) {
|
|
return desTemplate(data, key, AES_Algorithm, AES_Transformation, false); |
|
} |
|
|
|
/**
|
|
* DES加密模板
|
|
*
|
|
* @param data 数据
|
|
* @param key 秘钥
|
|
* @param algorithm 加密算法
|
|
* @param transformation 转变
|
|
* @param isEncrypt {@code true}: 加密 {@code false}: 解密
|
|
* @return 密文或者明文,适用于DES,3DES,AES
|
|
*/
|
|
public static byte[] desTemplate(byte[] data, byte[] key, String algorithm, String transformation, boolean isEncrypt) {
|
|
if (data == null || data.length == 0 || key == null || key.length == 0) return null; |
|
try {
|
|
SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); |
|
Cipher cipher = Cipher.getInstance(transformation); |
|
SecureRandom random = new SecureRandom(); |
|
cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, random); |
|
return cipher.doFinal(data); |
|
} catch (Throwable e) {
|
|
e.printStackTrace(); |
|
return null; |
|
} |
|
} |
|
|
|
private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; |
|
|
|
/**
|
|
* byteArr转hexString
|
|
* <p>例如:</p>
|
|
* bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8
|
|
*
|
|
* @param bytes 字节数组
|
|
* @return 16进制大写字符串
|
|
*/
|
|
private static String bytes2HexString(byte[] bytes) {
|
|
if (bytes == null) return null; |
|
int len = bytes.length; |
|
if (len <= 0) return null; |
|
char[] ret = new char[len << 1]; |
|
for (int i = 0, j = 0; i < len; i++) {
|
|
ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f]; |
|
ret[j++] = hexDigits[bytes[i] & 0x0f]; |
|
} |
|
return new String(ret); |
|
} |
|
|
|
|
|
/**
|
|
* hexString转byteArr
|
|
* <p>例如:</p>
|
|
* hexString2Bytes("00A8") returns { 0, (byte) 0xA8 }
|
|
*
|
|
* @param hexString 十六进制字符串
|
|
* @return 字节数组
|
|
*/
|
|
private static byte[] hexString2Bytes(String hexString) {
|
|
if (isSpace(hexString)) return null; |
|
int len = hexString.length(); |
|
if (len % 2 != 0) {
|
|
hexString = "0" + hexString; |
|
len = len + 1; |
|
} |
|
char[] hexBytes = hexString.toUpperCase().toCharArray(); |
|
byte[] ret = new byte[len >> 1]; |
|
for (int i = 0; i < len; i += 2) {
|
|
ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1])); |
|
} |
|
return ret; |
|
} |
|
|
|
/**
|
|
* hexChar转int
|
|
*
|
|
* @param hexChar hex单个字节
|
|
* @return 0..15
|
|
*/
|
|
private static int hex2Dec(char hexChar) {
|
|
if (hexChar >= '0' && hexChar <= '9') {
|
|
return hexChar - '0'; |
|
} else if (hexChar >= 'A' && hexChar <= 'F') {
|
|
return hexChar - 'A' + 10; |
|
} else {
|
|
throw new IllegalArgumentException(); |
|
} |
|
} |
|
|
|
/**
|
|
* Base64编码
|
|
*
|
|
* @param input 要编码的字节数组
|
|
* @return Base64编码后的字符串
|
|
*/
|
|
private static byte[] base64Encode(byte[] input) {
|
|
return Base64.encode(input, Base64.NO_WRAP); |
|
} |
|
|
|
/**
|
|
* Base64解码
|
|
*
|
|
* @param input 要解码的字符串
|
|
* @return Base64解码后的字符串
|
|
*/
|
|
private static byte[] base64Decode(byte[] input) {
|
|
return Base64.decode(input, Base64.NO_WRAP); |
|
} |
|
|
|
private static boolean isSpace(String s) {
|
|
if (s == null) return true; |
|
for (int i = 0, len = s.length(); i < len; ++i) {
|
|
if (!Character.isWhitespace(s.charAt(i))) {
|
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
} |