JAVA -> 数据加密和解密 留存
来源网站:https://www.cnblogs.com/itgungnir/p/6210936.html
1、Base64工具类(可逆):
import java.util.HashMap; import java.util.Map; /** * Base64加解密算法 * </p> * Base64加密算法:<br/> * 1、获取字符串中每个字符的ASCII码;<br/> * 2、按照每3个8bit的字符为一组来分组,即每组24bit;<br/> * 3、将这24bit划分成4个6bit的4个单位,每个单位前面添加2个0,得到4个8bit的单位;<br/> * 4、将每个8bit的单位转换成十进制数字,对照Base64编码表找到对应的字符进行拼接,得到最终的加密后的字符串。<br/> * </p> * Base64解密算法:<br/> * 1、读入4个字符,对照Base64编码表找到字符对应的索引,生成4个6为的值;<br/> * 2、将这4个6为的值拼接起来,形成一个24为的值;<br/> * 3、将这个24位的值按照8位一组截断成3个8位的值;<br/> * 4、对照ASCII表找到这三个8位的值对应的字符,即解码后的字符。<br/> * </p> * 注意事项:<br/> * 1、被编码的字符必须是8bit的,即必须在ASCII码范围内,中文不行;<br/> * 2、如果被编码的字符长度不是3的倍数,则在最后添加1或2个0,对应的输出字符为“=”; * 3、给定一个字符串,用Base64方法对其进行加密后解密,得到的结果就不是开始时候的字符串了。<br/> */ public class BASE64Util { private static final Map<Integer, Character> base64CharMap = new HashMap<>(); private static final String base64CharString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; private static BASE64Util instance; private BASE64Util() { for (int i = 0; i < base64CharString.length(); i++) { char c = base64CharString.charAt(i); base64CharMap.put(new Integer(i), new Character(c)); } } public static BASE64Util getInstance() { if (instance == null) { synchronized (BASE64Util.class) { if (instance == null) { instance = new BASE64Util(); } } } return instance; } /** * This method is used to encode a normal string to base64 string @param * origin The String to be encoded @return The String after encoded. */ public String encode(String origin) { if (origin == null) { return null; } if (origin.length() == 0) { return ""; } int length = origin.length(); String binaryString = ""; // to binary String for (int i = 0; i < length; i++) { int ascii = origin.charAt(i); String binaryCharString = Integer.toBinaryString(ascii); while (binaryCharString.length() < 8) { binaryCharString = "0" + binaryCharString; } binaryString += binaryCharString; } // to base64 index int beginIndex = 0; int endIndex = beginIndex + 6; String base64BinaryString = ""; String charString = ""; while ((base64BinaryString = binaryString.substring(beginIndex, endIndex)).length() > 0) { // if length is less than 6, add "0". while (base64BinaryString.length() < 6) { base64BinaryString += "0"; } int index = Integer.parseInt(base64BinaryString, 2); char base64Char = base64CharMap.get(index); charString = charString + base64Char; beginIndex += 6; endIndex += 6; if (endIndex >= binaryString.length()) { endIndex = binaryString.length(); } if (endIndex < beginIndex) { break; } } if (length % 3 == 2) { charString += "="; } if (length % 3 == 1) { charString += "=="; } return charString; } public String decode(String encodedString) { if (encodedString == null) { return null; } if (encodedString.length() == 0) { return ""; } // get origin base64 String String origin = encodedString.substring(0, encodedString.indexOf("=")); String equals = encodedString.substring(encodedString.indexOf("=")); String binaryString = ""; // convert base64 string to binary string for (int i = 0; i < origin.length(); i++) { char c = origin.charAt(i); int ascii = base64CharString.indexOf(c); String binaryCharString = Integer.toBinaryString(ascii); while (binaryCharString.length() < 6) { binaryCharString = "0" + binaryCharString; } binaryString += binaryCharString; } // the encoded string has 1 "=", means that the binary string has append // 2 "0" if (equals.length() == 1) { binaryString = binaryString.substring(0, binaryString.length() - 2); } // the encoded string has 2 "=", means that the binary string has append // 4 "0" if (equals.length() == 2) { binaryString = binaryString.substring(0, binaryString.length() - 4); } // convert to String String charString = ""; String resultString = ""; int beginIndex = 0; int endIndex = beginIndex + 8; while ((charString = binaryString.substring(beginIndex, endIndex)).length() == 8) { int ascii = Integer.parseInt(charString, 2); resultString += (char) ascii; beginIndex += 8; endIndex += 8; if (endIndex > binaryString.length()) { break; } } return resultString; } }
2、MD5工具类(不可逆):
import java.security.MessageDigest; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class MD5Util { public static final String MD5 = "MD5"; public static final String HmacMD5 = "HmacMD5"; public static final String charset = null; // 编码格式;默认null为GBK private static MD5Util instance; private MD5Util() { } // 单例 public static MD5Util getInstance() { if (instance == null) { synchronized (MD5Util.class) { if (instance == null) { instance = new MD5Util(); } } } return instance; } /** * 使用 MD5 方法加密(无密码) */ public String encode(String res) { try { MessageDigest md = MessageDigest.getInstance(MD5); byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset); return BASE64Util.getInstance().encode(md.digest(resBytes).toString()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 使用 MD5 方法加密(可以设密码) */ public String encode(String res, String key) { try { SecretKey sk = null; if (key == null) { KeyGenerator kg = KeyGenerator.getInstance(HmacMD5); sk = kg.generateKey(); } else { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); sk = new SecretKeySpec(keyBytes, HmacMD5); } Mac mac = Mac.getInstance(HmacMD5); mac.init(sk); byte[] result = mac.doFinal(res.getBytes()); return BASE64Util.getInstance().encode(result.toString()); } catch (Exception e) { e.printStackTrace(); } return null; } }
3、SHA1工具类(不可逆):
import java.security.MessageDigest; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * 使用 SHA1 方法进行加密<br/> * SHA1方法加密是不可逆的,不能解密,要想解密就必须使用暴力解密<br/> * <p/> * 方法中的 res 参数:原始的数据<br/> * 方法中的 key 参数:密钥,可以随便写<br/> */ public class SHA1Util { public static final String SHA1 = "SHA1"; public static final String HmacSHA1 = "HmacSHA1"; public static final String charset = null; // 编码格式;默认null为GBK private static SHA1Util instance; private SHA1Util() { } // 单例 public static SHA1Util getInstance() { if (instance == null) { synchronized (SHA1Util.class) { if (instance == null) { instance = new SHA1Util(); } } } return instance; } /** * 使用 SHA1 方法加密(无密码) */ public String encode(String res) { try { MessageDigest md = MessageDigest.getInstance(SHA1); byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset); return BASE64Util.getInstance().encode(md.digest(resBytes).toString()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 使用 SHA1 方法加密(可以设密码) */ public String encode(String res, String key) { try { SecretKey sk = null; if (key == null) { KeyGenerator kg = KeyGenerator.getInstance(HmacSHA1); sk = kg.generateKey(); } else { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); sk = new SecretKeySpec(keyBytes, HmacSHA1); } Mac mac = Mac.getInstance(HmacSHA1); mac.init(sk); byte[] result = mac.doFinal(res.getBytes()); return BASE64Util.getInstance().encode(result.toString()); } catch (Exception e) { e.printStackTrace(); } return null; } }
4、AES工具类(可逆):
import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class AESUtil { public static final String AES = "AES"; public static final String charset = null; // 编码格式;默认null为GBK public static final int keysizeAES = 128; private static AESUtil instance; private AESUtil() { } // 单例 public static AESUtil getInstance() { if (instance == null) { synchronized (MD5Util.class) { if (instance == null) { instance = new AESUtil(); } } } return instance; } /** * 使用 AES 进行加密 */ public String encode(String res, String key) { return keyGeneratorES(res, AES, key, keysizeAES, true); } /** * 使用 AES 进行解密 */ public String decode(String res, String key) { return keyGeneratorES(res, AES, key, keysizeAES, false); } // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错 private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) { try { KeyGenerator kg = KeyGenerator.getInstance(algorithm); if (keysize == 0) { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); kg.init(new SecureRandom(keyBytes)); } else if (key == null) { kg.init(keysize); } else { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); kg.init(keysize, new SecureRandom(keyBytes)); } SecretKey sk = kg.generateKey(); SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm); Cipher cipher = Cipher.getInstance(algorithm); if (isEncode) { cipher.init(Cipher.ENCRYPT_MODE, sks); byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset); return parseByte2HexStr(cipher.doFinal(resBytes)); } else { cipher.init(Cipher.DECRYPT_MODE, sks); return new String(cipher.doFinal(parseHexStr2Byte(res))); } } catch (Exception e) { e.printStackTrace(); } return null; } // 将二进制转换成16进制 private 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进制转换为二进制 private 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; } }
5、DES工具类(可逆):
import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class DESUtil { public static final String DES = "DES"; public static final String charset = null; // 编码格式;默认null为GBK public static final int keysizeDES = 0; private static DESUtil instance; private DESUtil() { } // 单例 public static DESUtil getInstance() { if (instance == null) { synchronized (MD5Util.class) { if (instance == null) { instance = new DESUtil(); } } } return instance; } /** * 使用 DES 进行加密 */ public String encode(String res, String key) { return keyGeneratorES(res, DES, key, keysizeDES, true); } /** * 使用 DES 进行解密 */ public String decode(String res, String key) { return keyGeneratorES(res, DES, key, keysizeDES, false); } // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错 private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) { try { KeyGenerator kg = KeyGenerator.getInstance(algorithm); if (keysize == 0) { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); kg.init(new SecureRandom(keyBytes)); } else if (key == null) { kg.init(keysize); } else { byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset); kg.init(keysize, new SecureRandom(keyBytes)); } SecretKey sk = kg.generateKey(); SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm); Cipher cipher = Cipher.getInstance(algorithm); if (isEncode) { cipher.init(Cipher.ENCRYPT_MODE, sks); byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset); return parseByte2HexStr(cipher.doFinal(resBytes)); } else { cipher.init(Cipher.DECRYPT_MODE, sks); return new String(cipher.doFinal(parseHexStr2Byte(res))); } } catch (Exception e) { e.printStackTrace(); } return null; } // 将二进制转换成16进制 private 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进制转换为二进制 private 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; } }
6、XOR(异或加密)工具类(可逆):
public class XORUtil { private static XORUtil instance; private XORUtil() { } // 单例 public static XORUtil getInstance() { if (instance == null) { synchronized (XORUtil.class) { if (instance == null) { instance = new XORUtil(); } } } return instance; } /** * 对一个数字进行异或加解密 */ public int code(int res, String key) { return res ^ key.hashCode(); } /** * 异或加密 */ public String encode(String res, String key) { byte[] bs = res.getBytes(); for (int i = 0; i < bs.length; i++) { bs[i] = (byte) ((bs[i]) ^ key.hashCode()); } return parseByte2HexStr(bs); } /** * 异或解密 */ public String decode(String res, String key) { byte[] bs = parseHexStr2Byte(res); for (int i = 0; i < bs.length; i++) { bs[i] = (byte) ((bs[i]) ^ key.hashCode()); } return new String(bs); } // 将二进制转换成16进制 private 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进制转换为二进制 private 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; } }
7、测试:
public class Test { public static void main(String[] args) { int xorNum = 12345; String res = "I am the text to be encoded and decoded."; String key = "我是密钥key"; System.out.println("-------------------------BASE64--------------------------"); String base64_encodedStr = BASE64Util.getInstance().encode(res); System.out.println("加密:" + base64_encodedStr); System.out.println("解密:" + BASE64Util.getInstance().decode(base64_encodedStr)); System.out.println("-------------------------MD5--------------------------"); String md5_encodedStr = MD5Util.getInstance().encode(res); System.out.println("无密码加密:" + md5_encodedStr); System.out.println("有密码加密:" + MD5Util.getInstance().encode(md5_encodedStr, key)); System.out.println("-------------------------SHA1--------------------------"); String sha1_encodedStr = SHA1Util.getInstance().encode(res); System.out.println("无密码加密:" + sha1_encodedStr); System.out.println("有密码加密:" + SHA1Util.getInstance().encode(sha1_encodedStr, key)); System.out.println("-------------------------AES--------------------------"); String aes_encodedStr = AESUtil.getInstance().encode(res, key); System.out.println("加密:" + aes_encodedStr); System.out.println("解密:" + AESUtil.getInstance().decode(aes_encodedStr, key)); System.out.println("-------------------------DES--------------------------"); String des_encodedStr = DESUtil.getInstance().encode(res, key); System.out.println("加密:" + des_encodedStr); System.out.println("解密:" + DESUtil.getInstance().decode(des_encodedStr, key)); System.out.println("-------------------------XOR--------------------------"); String xor_encodedStr = XORUtil.getInstance().encode(res, key); System.out.println("文本加密:" + xor_encodedStr); System.out.println("文本解密:" + XORUtil.getInstance().decode(xor_encodedStr, key)); int xor_encodedNum = XORUtil.getInstance().code(xorNum, key); System.out.println("数字加密:" + xor_encodedNum); System.out.println("数字解密:" + XORUtil.getInstance().code(xor_encodedNum, key)); } }
测试结果: