public final class AESUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(AESUtils.class);
/**
* need
* 根据sKey,生成一个密钥
* @param seed
* @return
* @throws Exception
*/
public static SecretKey getSecretKey(byte[] seed) throws Exception {
// 加密没关系,SecureRandom是生成安全随机数序列,sKey.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有sKey就行
SecureRandom secureRandom = new SecureRandom(seed);
KeyGenerator keyGenerator = KeyGenerator.getInstance(Constants.KEY_ALGORITHM);
// 利用sKey作为随机数初始化出128位的key生产者
// keyGenerator.init(secureRandom);
keyGenerator.init(128,secureRandom);
//根据sKey,生成一个密钥
return keyGenerator.generateKey();
}
// public static byte[] encrypt(byte[] data, byte[] encryptKey, byte[] iv) {
// // 初始化向量
// IvParameterSpec zeroIv = new IvParameterSpec(iv);
// //need
// SecretKeySpec key = new SecretKeySpec(encryptKey, KEY_ALGORITHM);
// return encrypt(data, zeroIv, key);
// }
// public static byte[] decrypt(byte[] data, byte[] decryptKey, byte[] iv) {
// IvParameterSpec zeroIv = new IvParameterSpec(iv);
// SecretKeySpec key = new SecretKeySpec(decryptKey, KEY_ALGORITHM);
// return decrypt(data, zeroIv, key);
// }
// public static byte[] encrypt(byte[] data, IvParameterSpec zeroIv, SecretKeySpec keySpec) {
// try {
// Profiler.enter("time cost on [aes encrypt]: data length=" + data.length);
// Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_PADDING);
// cipher.init(Cipher.ENCRYPT_MODE, keySpec, zeroIv);
// return cipher.doFinal(data);
// } catch (Exception e) {
// LOGGER.error("AES encrypt ex, iv={}, key={}",
// Arrays.toString(zeroIv.getIV()),
// Arrays.toString(keySpec.getEncoded()), e);
// throw new CryptoException("AES encrypt ex", e);
// } finally {
// Profiler.release();
// }
// }
// public static byte[] decrypt(byte[] data, IvParameterSpec zeroIv, SecretKeySpec keySpec) {
// try {
// Profiler.enter("time cost on [aes decrypt]: data length=" + data.length);
// Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_PADDING);
// cipher.init(Cipher.DECRYPT_MODE, keySpec, zeroIv);
// return cipher.doFinal(data);
// } catch (Exception e) {
// LOGGER.error("AES decrypt ex, iv={}, key={}",
// Arrays.toString(zeroIv.getIV()),
// Arrays.toString(keySpec.getEncoded()), e);
// throw new CryptoException("AES decrypt ex", e);
// } finally {
// Profiler.release();
// }
// }
//-----------------------------------------------------------------
/**
* 加密字符串
*
* @param content 需要加密的内容
* @param sKey 加密时的密码
* @return
*/
public static byte[] encrypt(String content, String sKey) {
try {
// 初始化加密器(加密)
Cipher cipher = initAESCipher(sKey, Cipher.ENCRYPT_MODE);
// content基本编码格式 -- 加密
return cipher.doFinal(content.getBytes(Constants.UTF_8));
} catch (IllegalBlockSizeException e) {
LOGGER.error("encrypt ex {}", e);
throw new CryptoException("encrypt ex", e);
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密字符串
*
* @param content AES加密过的内容
* @param sKey 密钥
* @return 明文
*/
public static byte[] decrypt(byte[] content, String sKey) {
try {
// 初始化加密器(加密)
Cipher cipher = initAESCipher(sKey, Cipher.DECRYPT_MODE);
// 明文
return cipher.doFinal(content);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* 对文件进行AES加密
*
* @param sourceFile
* @param encrypfile
* @param sKey
* @return
*/
public static File encryptFile(File sourceFile, File encrypfile, String sKey) {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(sourceFile);
outputStream = new FileOutputStream(encrypfile);
Cipher cipher = initAESCipher(sKey, Cipher.ENCRYPT_MODE);
// 以加密流写入文件
CipherInputStream cipherInputStream = new CipherInputStream(
inputStream, cipher);
byte[] cache = new byte[1024];
int nRead = 0;
while ((nRead = cipherInputStream.read(cache)) != -1) {
// write
outputStream.write(cache, 0, nRead);
outputStream.flush();
}
cipherInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return encrypfile;
}
/**
* AES方式解密文件
* @param sourceFile 要解密的文件路径
* @param decryptFile 解密后的文件路径
* @param sKey
* @return
*/
public static File decryptFile(File sourceFile, File decryptFile,
String sKey) {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
Cipher cipher = initAESCipher(sKey, Cipher.DECRYPT_MODE);
inputStream = new FileInputStream(sourceFile);
outputStream = new FileOutputStream(decryptFile);
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, cipher);
byte[] buffer = new byte[1024];
int r;
while ((r = inputStream.read(buffer)) >= 0) {
cipherOutputStream.write(buffer, 0, r);
}
cipherOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return decryptFile;
}
/**
* 初始化 AES Cipher
*
* @param sKey 秘钥?
* @param cipherMode
* @return Cipher 密码
*/
public static Cipher initAESCipher(String sKey, int cipherMode) {
// // 创建AES的Key生产者
KeyGenerator keyGenerator = null;
Cipher cipher = null;
try {
byte[] seed=sKey.getBytes();
SecretKey secretKey = getSecretKey(seed);
//AES
// keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
// keyGenerator.init(128, new SecureRandom(sKey.getBytes()));
// SecretKey secretKey = keyGenerator.generateKey();
// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回null
byte[] codeFormat = secretKey.getEncoded();
//转换为AES专用密钥
SecretKeySpec key = new SecretKeySpec(codeFormat, Constants.KEY_ALGORITHM);
//创建密码器
cipher = Cipher.getInstance(Constants.KEY_ALGORITHM);
//初始化为加密模式的密码器
cipher.init(cipherMode, key);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return cipher;
}
public static void main(String[] args) throws Exception {
// String cKey = "00b09e37363e596e1f25b23c78e49939238b";
// //未加密文件路径
// File oldfile = new File("C:\\Users\\Desktop\\test.mp4");
// //加密后的文件路径
// File encrypfile = new File("C:\\Users\\Desktop\\encryp.mp4");
// //解密后的文件路径
// File decrypfile = new File("C:\\Users\\Desktop\\decryp.mp4");
// //加密文件
// encryptFile(oldfile,encrypfile,cKey);
// //解密文件
// decryptFile(encrypfile, decrypfile,cKey);
String content = "你是人吗?";
// AES加密秘钥
String password = "FA141";
System.out.println("加密之前:" + content);
// 加密
byte[] encrypt = encrypt(content, password);
// 如果直接输出加密后的内容是一个乱码。我们需要把它的进制转换一下Hex
System.out.println("加密后的内容2进制:" + new String(encrypt));
//如果想要加密内容不显示乱码,可以先将密文转换为16进制
String hexStrResult = ParseSystemUtils.parseByte2HexStr(encrypt);
System.out.println("16进制的密文:" + hexStrResult);
//如果的到的是16进制密文,别忘了先转为2进制再解密
//byte[] binResult = ParseSystemUtils.parseHexStr2Byte(hexStrResult);
// 解密
byte[] decrypt = decrypt(encrypt, password);
System.out.println("解密后的内容:" + new String(decrypt));
}
}
public interface Constants {
Charset UTF_8 = StandardCharsets.UTF_8;
String KEY_ALGORITHM = "AES";
String KEY_ALGORITHM_PADDING = "AES/CBC/PKCS5Padding";
byte[] EMPTY_BYTES = new byte[0];
String HTTP_HEAD_READ_TIMEOUT = "readTimeout";
String EMPTY_STRING = "";
String ANY_HOST = "0.0.0.0";
String KICK_CHANNEL_PREFIX = "/mom/kick/";
}
public class ParseSystemUtils {
/**将二进制转换成16进制
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++) {
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}