Java加解密
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..."); } }