package cn.hotapk.fastandrutils.utils; import android.util.Base64; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.DigestInputStream; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; /** * @author laijian * @version 2017/9/20 * @Copyright (C)下午2:54 , www.hotapk.cn * 加密相关 */ public final class FEncryptUtils { private static final String DES_Algorithm = "DES"; /////////////////////////////////////////////////////////////////////////// // 哈希加密相关 /////////////////////////////////////////////////////////////////////////// private static final String TripleDES_Algorithm = "DESede"; private static final String AES_Algorithm = "AES"; private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; /** * DES转变 *

法算法名称/加密模式/填充方式

*

加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB

*

填充方式有:NoPadding、ZerosPadding、PKCS5Padding

*/ public static String DES_Transformation = "DES/ECB/NoPadding"; /** * 3DES转变 *

法算法名称/加密模式/填充方式

*

加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB

*

填充方式有:NoPadding、ZerosPadding、PKCS5Padding

*/ public static String TripleDES_Transformation = "DESede/ECB/NoPadding"; /** * AES转变 *

法算法名称/加密模式/填充方式

*

加密模式有:电子密码本模式ECB、加密块链模式CBC、加密反馈模式CFB、输出反馈模式OFB

*

填充方式有:NoPadding、ZerosPadding、PKCS5Padding

*/ public static String AES_Transformation = "AES/ECB/NoPadding"; private FEncryptUtils() { } /** * MD2加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptMD2ToString(final String data) { return encryptMD2ToString(data.getBytes()); } /** * MD2加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptMD2ToString(final byte[] data) { return bytes2HexString(encryptMD2(data)); } /** * MD2加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptMD2(final byte[] data) { return hashTemplate(data, "MD2"); } /** * MD5加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptMD5ToString(final String data) { return encryptMD5ToString(data.getBytes()); } /** * MD5加密 * * @param data 明文字符串 * @param salt 盐 * @return 16进制加盐密文 */ public static String encryptMD5ToString(final String data, final String salt) { return bytes2HexString(encryptMD5((data + salt).getBytes())); } /** * MD5加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptMD5ToString(final byte[] data) { return bytes2HexString(encryptMD5(data)); } /** * MD5加密 * * @param data 明文字节数组 * @param salt 盐字节数组 * @return 16进制加盐密文 */ public static String encryptMD5ToString(final byte[] data, final byte[] salt) { if (data == null || salt == null) return null; byte[] dataSalt = new byte[data.length + salt.length]; System.arraycopy(data, 0, dataSalt, 0, data.length); System.arraycopy(salt, 0, dataSalt, data.length, salt.length); return bytes2HexString(encryptMD5(dataSalt)); } /** * MD5加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptMD5(final byte[] data) { return hashTemplate(data, "MD5"); } /** * MD5加密文件 * * @param filePath 文件路径 * @return 文件的16进制密文 */ public static String encryptMD5File2String(final String filePath) { File file = isSpace(filePath) ? null : new File(filePath); return encryptMD5File2String(file); } /** * MD5加密文件 * * @param filePath 文件路径 * @return 文件的MD5校验码 */ public static byte[] encryptMD5File(final String filePath) { File file = isSpace(filePath) ? null : new File(filePath); return encryptMD5File(file); } /** * MD5加密文件 * * @param file 文件 * @return 文件的16进制密文 */ public static String encryptMD5File2String(final File file) { return bytes2HexString(encryptMD5File(file)); } /** * MD5加密文件 * * @param file 文件 * @return 文件的MD5校验码 */ public static byte[] encryptMD5File(final File file) { if (file == null) return null; FileInputStream fis = null; DigestInputStream digestInputStream; try { fis = new FileInputStream(file); MessageDigest md = MessageDigest.getInstance("MD5"); digestInputStream = new DigestInputStream(fis, md); byte[] buffer = new byte[256 * 1024]; while (true) { if (!(digestInputStream.read(buffer) > 0)) break; } md = digestInputStream.getMessageDigest(); return md.digest(); } catch (NoSuchAlgorithmException | IOException e) { e.printStackTrace(); return null; } finally { FCloseUtils.closeIO(fis); } } /** * SHA1加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptSHA1ToString(final String data) { return encryptSHA1ToString(data.getBytes()); } /** * SHA1加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptSHA1ToString(final byte[] data) { return bytes2HexString(encryptSHA1(data)); } /** * SHA1加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptSHA1(final byte[] data) { return hashTemplate(data, "SHA1"); } /** * SHA224加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptSHA224ToString(final String data) { return encryptSHA224ToString(data.getBytes()); } /** * SHA224加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptSHA224ToString(final byte[] data) { return bytes2HexString(encryptSHA224(data)); } /** * SHA224加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptSHA224(final byte[] data) { return hashTemplate(data, "SHA224"); } /** * SHA256加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptSHA256ToString(final String data) { return encryptSHA256ToString(data.getBytes()); } /** * SHA256加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptSHA256ToString(final byte[] data) { return bytes2HexString(encryptSHA256(data)); } /** * SHA256加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptSHA256(final byte[] data) { return hashTemplate(data, "SHA256"); } /** * SHA384加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptSHA384ToString(final String data) { return encryptSHA384ToString(data.getBytes()); } /** * SHA384加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptSHA384ToString(final byte[] data) { return bytes2HexString(encryptSHA384(data)); } /** * SHA384加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptSHA384(final byte[] data) { return hashTemplate(data, "SHA384"); } /** * SHA512加密 * * @param data 明文字符串 * @return 16进制密文 */ public static String encryptSHA512ToString(final String data) { return encryptSHA512ToString(data.getBytes()); } /** * SHA512加密 * * @param data 明文字节数组 * @return 16进制密文 */ public static String encryptSHA512ToString(final byte[] data) { return bytes2HexString(encryptSHA512(data)); } /** * SHA512加密 * * @param data 明文字节数组 * @return 密文字节数组 */ public static byte[] encryptSHA512(final byte[] data) { return hashTemplate(data, "SHA512"); } /** * hash加密模板 * * @param data 数据 * @param algorithm 加密算法 * @return 密文字节数组 */ private static byte[] hashTemplate(final byte[] data, final String algorithm) { if (data == null || data.length <= 0) return null; try { MessageDigest md = MessageDigest.getInstance(algorithm); md.update(data); return md.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * HmacMD5加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacMD5ToString(final String data, final String key) { return encryptHmacMD5ToString(data.getBytes(), key.getBytes()); } /** * HmacMD5加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacMD5ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacMD5(data, key)); } /** * HmacMD5加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacMD5(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacMD5"); } /** * HmacSHA1加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA1ToString(final String data, final String key) { return encryptHmacSHA1ToString(data.getBytes(), key.getBytes()); } /** * HmacSHA1加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA1ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacSHA1(data, key)); } /** * HmacSHA1加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacSHA1(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacSHA1"); } /** * HmacSHA224加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA224ToString(final String data, final String key) { return encryptHmacSHA224ToString(data.getBytes(), key.getBytes()); } /** * HmacSHA224加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA224ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacSHA224(data, key)); } /** * HmacSHA224加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacSHA224(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacSHA224"); } /** * HmacSHA256加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA256ToString(final String data, final String key) { return encryptHmacSHA256ToString(data.getBytes(), key.getBytes()); } /** * HmacSHA256加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA256ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacSHA256(data, key)); } /** * HmacSHA256加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacSHA256(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacSHA256"); } /////////////////////////////////////////////////////////////////////////// // DES加密相关 /////////////////////////////////////////////////////////////////////////// /** * HmacSHA384加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA384ToString(final String data, final String key) { return encryptHmacSHA384ToString(data.getBytes(), key.getBytes()); } /** * HmacSHA384加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA384ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacSHA384(data, key)); } /** * HmacSHA384加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacSHA384(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacSHA384"); } /** * HmacSHA512加密 * * @param data 明文字符串 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA512ToString(final String data, final String key) { return encryptHmacSHA512ToString(data.getBytes(), key.getBytes()); } /** * HmacSHA512加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 16进制密文 */ public static String encryptHmacSHA512ToString(final byte[] data, final byte[] key) { return bytes2HexString(encryptHmacSHA512(data, key)); } /** * HmacSHA512加密 * * @param data 明文字节数组 * @param key 秘钥 * @return 密文字节数组 */ public static byte[] encryptHmacSHA512(final byte[] data, final byte[] key) { return hmacTemplate(data, key, "HmacSHA512"); } /** * Hmac加密模板 * * @param data 数据 * @param key 秘钥 * @param algorithm 加密算法 * @return 密文字节数组 */ private static byte[] hmacTemplate(final byte[] data, final byte[] key, final String algorithm) { if (data == null || data.length == 0 || key == null || key.length == 0) return null; try { SecretKeySpec secretKey = new SecretKeySpec(key, algorithm); Mac mac = Mac.getInstance(algorithm); mac.init(secretKey); return mac.doFinal(data); } catch (InvalidKeyException | NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * DES加密后转为Base64编码 * * @param data 明文 * @param key 8字节秘钥 * @return Base64密文 */ public static byte[] encryptDES2Base64(final byte[] data, final byte[] key) { return base64Encode(encryptDES(data, key)); } /////////////////////////////////////////////////////////////////////////// // 3DES加密相关 /////////////////////////////////////////////////////////////////////////// /** * DES加密后转为16进制 * * @param data 明文 * @param key 8字节秘钥 * @return 16进制密文 */ public static String encryptDES2HexString(final byte[] data, final byte[] key) { return bytes2HexString(encryptDES(data, key)); } /** * DES加密 * * @param data 明文 * @param key 8字节秘钥 * @return 密文 */ public static byte[] encryptDES(final byte[] data, final byte[] key) { return desTemplate(data, key, DES_Algorithm, DES_Transformation, true); } /** * DES解密Base64编码密文 * * @param data Base64编码密文 * @param key 8字节秘钥 * @return 明文 */ public static byte[] decryptBase64DES(final byte[] data, final byte[] key) { return decryptDES(base64Decode(data), key); } /** * DES解密16进制密文 * * @param data 16进制密文 * @param key 8字节秘钥 * @return 明文 */ public static byte[] decryptHexStringDES(final String data, final byte[] key) { return decryptDES(hexString2Bytes(data), key); } /** * DES解密 * * @param data 密文 * @param key 8字节秘钥 * @return 明文 */ public static byte[] decryptDES(final byte[] data, final byte[] key) { return desTemplate(data, key, DES_Algorithm, DES_Transformation, false); } /** * 3DES加密后转为Base64编码 * * @param data 明文 * @param key 24字节秘钥 * @return Base64密文 */ public static byte[] encrypt3DES2Base64(final byte[] data, final byte[] key) { return base64Encode(encrypt3DES(data, key)); } /** * 3DES加密后转为16进制 * * @param data 明文 * @param key 24字节秘钥 * @return 16进制密文 */ public static String encrypt3DES2HexString(final byte[] data, final byte[] key) { return bytes2HexString(encrypt3DES(data, key)); } /** * 3DES加密 * * @param data 明文 * @param key 24字节密钥 * @return 密文 */ public static byte[] encrypt3DES(final byte[] data, final byte[] key) { return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, true); } /////////////////////////////////////////////////////////////////////////// // AES加密相关 /////////////////////////////////////////////////////////////////////////// /** * 3DES解密Base64编码密文 * * @param data Base64编码密文 * @param key 24字节秘钥 * @return 明文 */ public static byte[] decryptBase64_3DES(final byte[] data, final byte[] key) { return decrypt3DES(base64Decode(data), key); } /** * 3DES解密16进制密文 * * @param data 16进制密文 * @param key 24字节秘钥 * @return 明文 */ public static byte[] decryptHexString3DES(final String data, final byte[] key) { return decrypt3DES(hexString2Bytes(data), key); } /** * 3DES解密 * * @param data 密文 * @param key 24字节密钥 * @return 明文 */ public static byte[] decrypt3DES(final byte[] data, final byte[] key) { return desTemplate(data, key, TripleDES_Algorithm, TripleDES_Transformation, false); } /** * AES加密后转为Base64编码 * * @param data 明文 * @param key 16、24、32字节秘钥 * @return Base64密文 */ public static byte[] encryptAES2Base64(final byte[] data, final byte[] key) { return base64Encode(encryptAES(data, key)); } /** * AES加密后转为16进制 * * @param data 明文 * @param key 16、24、32字节秘钥 * @return 16进制密文 */ public static String encryptAES2HexString(final byte[] data, final byte[] key) { return bytes2HexString(encryptAES(data, key)); } /** * AES加密 * * @param data 明文 * @param key 16、24、32字节秘钥 * @return 密文 */ public static byte[] encryptAES(final byte[] data, final byte[] key) { return desTemplate(data, key, AES_Algorithm, AES_Transformation, true); } /** * AES解密Base64编码密文 * * @param data Base64编码密文 * @param key 16、24、32字节秘钥 * @return 明文 */ public static byte[] decryptBase64AES(final byte[] data, final byte[] key) { return decryptAES(base64Decode(data), key); } /** * AES解密16进制密文 * * @param data 16进制密文 * @param key 16、24、32字节秘钥 * @return 明文 */ public static byte[] decryptHexStringAES(final String data, final byte[] key) { return decryptAES(hexString2Bytes(data), key); } /** * AES解密 * * @param data 密文 * @param key 16、24、32字节秘钥 * @return 明文 */ public static byte[] decryptAES(final byte[] data, final byte[] key) { return desTemplate(data, key, AES_Algorithm, AES_Transformation, false); } /** * DES加密模板 * * @param data 数据 * @param key 秘钥 * @param algorithm 加密算法 * @param transformation 转变 * @param isEncrypt {@code true}: 加密 {@code false}: 解密 * @return 密文或者明文,适用于DES,3DES,AES */ public static byte[] desTemplate(final byte[] data, final byte[] key, final String algorithm, final String transformation, final boolean isEncrypt) { if (data == null || data.length == 0 || key == null || key.length == 0) return null; try { SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); Cipher cipher = Cipher.getInstance(transformation); SecureRandom random = new SecureRandom(); cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, random); return cipher.doFinal(data); } catch (Throwable e) { e.printStackTrace(); return null; } } private static String bytes2HexString(final byte[] bytes) { if (bytes == null) return null; int len = bytes.length; if (len <= 0) return null; char[] ret = new char[len << 1]; for (int i = 0, j = 0; i < len; i++) { ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f]; ret[j++] = hexDigits[bytes[i] & 0x0f]; } return new String(ret); } private static byte[] hexString2Bytes(String hexString) { if (isSpace(hexString)) return null; int len = hexString.length(); if (len % 2 != 0) { hexString = "0" + hexString; len = len + 1; } char[] hexBytes = hexString.toUpperCase().toCharArray(); byte[] ret = new byte[len >> 1]; for (int i = 0; i < len; i += 2) { ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1])); } return ret; } private static int hex2Dec(final char hexChar) { if (hexChar >= '0' && hexChar <= '9') { return hexChar - '0'; } else if (hexChar >= 'A' && hexChar <= 'F') { return hexChar - 'A' + 10; } else { throw new IllegalArgumentException(); } } private static byte[] base64Encode(final byte[] input) { return Base64.encode(input, Base64.NO_WRAP); } private static byte[] base64Decode(final byte[] input) { return Base64.decode(input, Base64.NO_WRAP); } /** * String转Base64字符串 * * @param message the message * @return the string */ public static String stringToBase64(String message) { return Base64.encodeToString(message.getBytes(), Base64.DEFAULT); } /** * Base64字符串转bytes * * @param base64Message the message * @return the string */ public static byte[] base64ToByte(String base64Message) { return Base64.decode(base64Message, Base64.DEFAULT); } /** * 对字符串md5加密 * * @param str * @return */ public static String string2MD5(String str) { try { // 生成一个MD5加密计算摘要 MessageDigest md = MessageDigest.getInstance("MD5"); // 计算md5函数 md.update(str.getBytes()); // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 return new BigInteger(1, md.digest()).toString(16); } catch (Exception e) { return ""; } } private static boolean isSpace(final String s) { if (s == null) return true; for (int i = 0, len = s.length(); i < len; ++i) { if (!Character.isWhitespace(s.charAt(i))) { return false; } } return true; } }