1. 算法
1.1 AES
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public final class Encrypt {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
public static final String UTF_8 = "UTF-8";
/**
* 加密
*
* @param by
* 加密内容
* @param ivStr
* 加密iv,包括秘钥和盐值,中间用逗号分隔
* @return 密文
*/
public static byte[] encrypt(byte[] by, String ivStr) {
try {
String[] ivs = ivStr.split(",");
SecretKeySpec skeySpec = getKey(ivs[0]); // 秘钥
IvParameterSpec iv = new IvParameterSpec(ivs[1].getBytes(UTF_8)); // 盐值
Cipher encryptCipher = Cipher.getInstance(ALGORITHM);
encryptCipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = encryptCipher.doFinal(by);
return encrypted;
} catch (Exception e) {
System.out.println("encrypt exception: " + e);
}
return null;
}
/**
* 解密
*
* @param by
* 密文
* @param ivStr
* 解密iv,包括秘钥和盐值,中间用逗号分隔
* @return 明文
*/
public static byte[] decrypt(byte[] by, String ivStr) {
try {
String[] ivs = ivStr.split(",");
SecretKeySpec skeySpec = getKey(ivs[0]); // 秘钥
IvParameterSpec iv = new IvParameterSpec(ivs[1].getBytes(UTF_8)); // 盐值
Cipher decryptCipher = Cipher.getInstance(ALGORITHM);
decryptCipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
if (by != null) {
byte[] original = decryptCipher.doFinal(by);
return original;
}
} catch (Exception e) {
System.out.println("decrypt exception: " + e);
}
return null;
}
private static SecretKeySpec getKey(String strKey) throws UnsupportedEncodingException {
byte[] arrBTmp = strKey.getBytes(UTF_8);
byte[] arrB = new byte[16];
int length = arrBTmp.length < arrB.length ? arrBTmp.length : arrB.length;
System.arraycopy(arrBTmp, 0, arrB, 0, length);
SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
return skeySpec;
}
/**
* 将二进制转换成16进制
*
* @param buf
* byte
* @return String
*/
private 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();
}
/**
* 生成指定位数的随机字符串
*
* @param count
* 生成字符串位数为count*2
* @return 安全随机字符串
*/
public static String getRandom(int count) {
SecureRandom random = null;
try {
random = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
System.out.println("getRandom exception: " + e);
}
byte[] salt = new byte[count];
random.nextBytes(salt);
return parseByte2HexStr(salt);
}
public static void main(String[] args) throws Exception {
String ivKey = Encrypt.getRandom(16 / 2) + "," + Encrypt.getRandom(16 / 2);
// 对文本加解密
String content = "Hello world";
byte[] secret = Encrypt.encrypt(content.getBytes(Encrypt.UTF_8), ivKey); // 加密
System.out.println(new String(Encrypt.decrypt(secret, ivKey), Encrypt.UTF_8)); // 解密
// 对文件加解密
// (1) 打开文件流以字节方式读入,然后加密,最后写入文件
// (2) 打开文件流以字节方式读入,然后解密,最后写入文件
File src = new File("d:\\abc.txt");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
byte[] buf = new byte[(int) src.length()];
bis.read(buf);
bis.close();
byte[] ds = Encrypt.encrypt(buf, ivKey); // 加密
byte[] out = Encrypt.decrypt(ds, ivKey); // 解密
File dst = new File("d:\\cba.txt"); // 解密之后的文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dst));
bos.write(out);
bos.close();
System.out.println("test finished...");
}
}