工具類
/**
* AES加解密工具類, 使用Base64進(jìn)行編解碼
* String value = AESUtil.encrypt("mazaiting", "123456789");
Log.e("MainActivity", value);
Log.e("MainActivity", AESUtil.decrypt("mazaiting", value));
* Created by mazaiting on 2018/6/22.
*/
public class AESUtil {
/**密鑰長度*/
private static final int KEY_LENGTH = 16;
/**默認(rèn)填充位數(shù)*/
private static final String DEFAULT_VALUE = "0";
/**
* 加密
* @param key 密鑰
* @param src 加密文本
* @return 加密后的文本
* @throws Exception
*/
public static String encrypt(String key, String src) throws Exception {
// 對源數(shù)據(jù)進(jìn)行Base64編碼
src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT);
// 補(bǔ)全KEY為16位
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();
// 獲取加密后的字節(jié)數(shù)組
byte[] result = getBytes(rawKey, src.getBytes("utf-8"), Cipher.ENCRYPT_MODE);
// 對加密后的字節(jié)數(shù)組進(jìn)行Base64編碼
result = Base64.encode(result, Base64.DEFAULT);
// 返回字符串
return new String(result, Charset.defaultCharset());
}
/**
* 解密
* @param key 密鑰
* @param encrypted 待解密文本
* @return 返回解密后的數(shù)據(jù)
* @throws Exception
*/
public static String decrypt(String key, String encrypted) throws Exception {
// 補(bǔ)全KEY為16位
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();
// 獲取加密后的二進(jìn)制字節(jié)數(shù)組
byte[] enc = encrypted.getBytes(Charset.defaultCharset());
// 對二進(jìn)制數(shù)組進(jìn)行Base64解碼
enc = Base64.decode(enc, Base64.DEFAULT);
// 獲取解密后的二進(jìn)制字節(jié)數(shù)組
byte[] result = getBytes(rawKey, enc, Cipher.DECRYPT_MODE);
// 對解密后的二進(jìn)制數(shù)組進(jìn)行Base64解碼
result = Base64.decode(result, Base64.DEFAULT);
// 返回字符串
return new String(result, "utf-8");
}
/**
* 密鑰key ,默認(rèn)補(bǔ)的數(shù)字,補(bǔ)全16位數(shù),以保證安全補(bǔ)全至少16位長度,android和ios對接通過
* @param key 密鑰key
* @param length 密鑰應(yīng)有的長度
* @param text 默認(rèn)補(bǔ)的文本
* @return 密鑰
*/
private static String toMakeKey(String key, int length, String text) {
// 獲取密鑰長度
int strLen = key.length();
// 判斷長度是否小于應(yīng)有的長度
if (strLen < length) {
// 補(bǔ)全位數(shù)
StringBuilder builder = new StringBuilder();
// 將key添加至builder中
builder.append(key);
// 遍歷添加默認(rèn)文本
for (int i = 0; i < length - strLen; i++) {
builder.append(text);
}
// 賦值
key = builder.toString();
}
return key;
}
/**
* 加解密過程
* 1. 通過密鑰得到一個(gè)密鑰專用的對象SecretKeySpec
* 2. Cipher 加密算法钻心,加密模式和填充方式三部分或指定加密算 (可以只用寫算法然后用默認(rèn)的其他方式)Cipher.getInstance("AES");
* @param key 二進(jìn)制密鑰數(shù)組
* @param src 加解密的源二進(jìn)制數(shù)據(jù)
* @param mode 模式笨触,加密為:Cipher.ENCRYPT_MODE;解密為:Cipher.DECRYPT_MODE
* @return 加解密后的二進(jìn)制數(shù)組
* @throws NoSuchAlgorithmException 無效算法
* @throws NoSuchPaddingException 無效填充
* @throws InvalidKeyException 無效KEY
* @throws InvalidAlgorithmParameterException 無效密鑰
* @throws IllegalBlockSizeException 非法塊字節(jié)
* @throws BadPaddingException 壞數(shù)據(jù)
*/
private static byte[] getBytes(byte[] key, byte[] src, int mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
// 密鑰規(guī)格
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
// 密鑰實(shí)例
Cipher cipher = Cipher.getInstance("AES");
// 初始化密鑰模式
cipher.init(mode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
// 加密數(shù)據(jù)
return cipher.doFinal(src);
}
}
使用
String value = AESUtil.encrypt("mazaiting", "123456789");
Log.e("MainActivity", value);
Log.e("MainActivity", AESUtil.decrypt("mazaiting", value));
加密文件及字符串工具類
/**
* Aes加密工具類
* 使用:
* val value = AESUtil.encrypt("mazaiting", "123456789")
Log.e("MainActivity", value)
Log.e("MainActivity", AESUtil.decrypt("mazaiting", value))
*
* Created by mazaiting on 2018/6/21.
*/
public class AESUtil {
/**16進(jìn)制數(shù)*/
private final static String HEX = "0123456789ABCDEF";
/**密鑰長度*/
private static final int KEY_LENGTH = 16;
/**默認(rèn)填充位數(shù)*/
private static final String DEFAULT_VALUE = "0";
/**
* 加密
* @param key 密鑰
* @param src 加密文本
* @return 加密后的文本
* @throws Exception
*/
public static String encrypt(String key, String src) throws Exception {
// 對源數(shù)據(jù)進(jìn)行Base64編碼
src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT);
// 補(bǔ)全KEY為16位
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();
// 獲取加密后的字節(jié)數(shù)組
byte[] result = getBytes(rawKey, src.getBytes("utf-8"),"AES", Cipher.ENCRYPT_MODE);
// 對加密后的字節(jié)數(shù)組進(jìn)行Base64編碼
result = Base64.encode(result, Base64.DEFAULT);
// 返回字符串
return new String(result, Charset.defaultCharset());
}
/**
* 解密
* @param key 密鑰
* @param encrypted 待解密文本
* @return 返回解密后的數(shù)據(jù)
* @throws Exception
*/
public static String decrypt(String key, String encrypted) throws Exception {
// 補(bǔ)全KEY為16位
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();
// 獲取加密后的二進(jìn)制字節(jié)數(shù)組
byte[] enc = encrypted.getBytes(Charset.defaultCharset());
// 對二進(jìn)制數(shù)組進(jìn)行Base64解碼
enc = Base64.decode(enc, Base64.DEFAULT);
// 獲取解密后的二進(jìn)制字節(jié)數(shù)組
byte[] result = getBytes(rawKey, enc,"AES", Cipher.DECRYPT_MODE);
// 對解密后的二進(jìn)制數(shù)組進(jìn)行Base64解碼
result = Base64.decode(result, Base64.DEFAULT);
// 返回字符串
return new String(result, "utf-8");
}
/**
* 加密
* @param key 密鑰
* @param src 加密文本
* @return 加密后的數(shù)據(jù)
* @throws Exception
*/
public static String encrypt2Java(String key, String src) throws Exception {
// /src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT);
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();// key.getBytes();
// byte[] result = encrypt2Java(rawKey, src.getBytes("utf-8"));
byte[] result = getBytes(rawKey, src.getBytes("utf-8"), "AES/CBC/PKCS5Padding", Cipher.ENCRYPT_MODE);
// result = Base64.encode(result, Base64.DEFAULT);
return toHex(result);
}
/**
* 加密
* @param key 密鑰
* @param src 加密文本
* @return 加密后的數(shù)據(jù)
* @throws Exception
*/
public static String decrypt2Java(String key, String src) throws Exception {
// /src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT);
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();// key.getBytes();
byte[] result = getBytes(rawKey, src.getBytes("utf-8"), "AES/CBC/PKCS5Padding", Cipher.DECRYPT_MODE);
// result = Base64.encode(result, Base64.DEFAULT);
return toHex(result);
}
/**
* 密鑰key ,默認(rèn)補(bǔ)的數(shù)字,補(bǔ)全16位數(shù)姿染,以保證安全補(bǔ)全至少16位長度,android和ios對接通過
* @param key 密鑰key
* @param length 密鑰應(yīng)有的長度
* @param text 默認(rèn)補(bǔ)的文本
* @return 密鑰
*/
private static String toMakeKey(String key, int length, String text) {
// 獲取密鑰長度
int strLen = key.length();
// 判斷長度是否小于應(yīng)有的長度
if (strLen < length) {
// 補(bǔ)全位數(shù)
StringBuilder builder = new StringBuilder();
// 將key添加至builder中
builder.append(key);
// 遍歷添加默認(rèn)文本
for (int i = 0; i < length - strLen; i++) {
builder.append(text);
}
// 賦值
key = builder.toString();
}
return key;
}
/**
* 加解密過程
* 1. 通過密鑰得到一個(gè)密鑰專用的對象SecretKeySpec
* 2. Cipher 加密算法,加密模式和填充方式三部分或指定加密算 (可以只用寫算法然后用默認(rèn)的其他方式)Cipher.getInstance("AES");
* @param key 二進(jìn)制密鑰數(shù)組
* @param src 加解密的源二進(jìn)制數(shù)據(jù)
* @param mode 模式,加密為:Cipher.ENCRYPT_MODE;解密為:Cipher.DECRYPT_MODE
* @return 加解密后的二進(jìn)制數(shù)組
* @throws NoSuchAlgorithmException 無效算法
* @throws NoSuchPaddingException 無效填充
* @throws InvalidKeyException 無效KEY
* @throws InvalidAlgorithmParameterException 無效密鑰
* @throws IllegalBlockSizeException 非法塊字節(jié)
* @throws BadPaddingException 壞數(shù)據(jù)
*/
private static byte[] getBytes(byte[] key, byte[] src,String transformation, int mode) throws
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
// 密鑰規(guī)格
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
// 密鑰實(shí)例
Cipher cipher = Cipher.getInstance(transformation);
// 初始化密鑰模式
cipher.init(mode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
// 加密數(shù)據(jù)
return cipher.doFinal(src);
}
/**獲取16進(jìn)制字符串*/
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
/**將16進(jìn)制字符串轉(zhuǎn)換為未編碼后的數(shù)據(jù)*/
public static String fromHex(String hex) {
return new String(toByte(hex));
}
/**
* 把16進(jìn)制轉(zhuǎn)化為字節(jié)數(shù)組
* @param hexString 16進(jìn)制字符串
* @return 加密后的字節(jié)數(shù)組
*/
private static byte[] toByte(String hexString) {
// 獲取源數(shù)據(jù)長度
int len = hexString.length() / 2;
// 創(chuàng)建字節(jié)數(shù)組
byte[] result = new byte[len];
// 遍歷
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
// 返回二進(jìn)制字節(jié)數(shù)組
return result;
}
/**
* 二進(jìn)制轉(zhuǎn)字符,轉(zhuǎn)成了16進(jìn)制
* 0123456789abcdef
* @param bytes 字節(jié)組數(shù)
* @return 16進(jìn)制編碼的字符串
*/
private static String toHex(byte[] bytes) {
// 判斷二進(jìn)制數(shù)組長度是否小于0
if (bytes.length <= 0) return "";
// 創(chuàng)建字符串連接對象
StringBuilder builder = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
// 拼接字符
builder.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
// 返回字符串
return builder.toString();
}
/**
* 對文件進(jìn)行AES加密
* @param sourceFile 待加密文件
* @param toFile 加密后的文件
* @param dir 文件存儲(chǔ)路徑
* @param key 密鑰
* @return 加密后的文件
*/
public static File encryptFile(File sourceFile, String toFile, String dir, String key) {
// 新建臨時(shí)加密文件
File encryptFile = null;
// 輸入流
InputStream inputStream = null;
// 輸出流
OutputStream outputStream = null;
try {
// 讀取源文件芹扭,創(chuàng)建文件輸入流
inputStream = new FileInputStream(sourceFile);
// 創(chuàng)建加密后的文件
encryptFile = new File(dir + toFile);
// 根據(jù)文件創(chuàng)建輸出流
outputStream = new FileOutputStream(encryptFile);
// 初始化 Cipher
Cipher cipher = initAESCipher(key, Cipher.ENCRYPT_MODE);
// 以加密流寫入文件
CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
// 創(chuàng)建緩存字節(jié)數(shù)組
byte[] cache = new byte[1024];
// 讀取
int len;
// 讀取加密并寫入文件
while ((len = cipherInputStream.read(cache)) != -1) {
outputStream.write(cache, 0, len);
outputStream.flush();
}
// 關(guān)閉加密輸入流
cipherInputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
return encryptFile;
}
/**
* AES方式解密文件
* @param sourceFile 源文件
* @param toFile 目標(biāo)文件
* @param dir 文件存儲(chǔ)路徑
* @param key 密鑰
* @return
*/
public static File decryptFile(File sourceFile, String toFile, String dir, String key) {
// 解密文件
File decryptFile = null;
// 文件輸入流
InputStream inputStream = null;
// 文件輸出流
OutputStream outputStream = null;
try {
// 創(chuàng)建解密文件
decryptFile = new File(dir + toFile);
// 初始化Cipher
Cipher cipher = initAESCipher(key, Cipher.DECRYPT_MODE);
// 根據(jù)源文件創(chuàng)建輸入流
inputStream = new FileInputStream(sourceFile);
// 創(chuàng)建輸出流
outputStream = new FileOutputStream(decryptFile);
// 獲取解密輸出流
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
// 創(chuàng)建緩沖字節(jié)數(shù)組
byte[] buffer = new byte[1024];
int len;
// 讀取解密并寫入
while ((len = inputStream.read(buffer)) >= 0) {
cipherOutputStream.write(buffer, 0, len);
cipherOutputStream.flush();
}
// 關(guān)閉流
cipherOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
return decryptFile;
}
/**
* 初始化 AES Cipher
* @param key 密鑰
* @param cipherMode 加密模式
* @return 密鑰
*/
private static Cipher initAESCipher(String key, int cipherMode) {
Cipher cipher = null;
try {
// 將KEY進(jìn)行修正
byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();
// 創(chuàng)建密鑰規(guī)格
SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey, "AES");
// 獲取密鑰
cipher = Cipher.getInstance("AES");
// 初始化
cipher.init(cipherMode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
return cipher;
}
/**
* 關(guān)閉流
* @param closeable 實(shí)現(xiàn)Closeable接口
*/
private static void closeStream(Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}