package com.github.hunter0x7c7.sync.utils; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * AES加解密 */ public class AesUtil { //填充类型 public static final String AES_TYPE_CBC_PKCS5 = "AES/CBC/PKCS5Padding";// AES/CBC/PKCS7Padding public static final String AES_TYPE_ECB_PKCS5 = "AES/ECB/PKCS5Padding"; public static final String AES_TYPE_ECB_PKCS7 = "AES/ECB/PKCS7Padding"; //此类型 加密内容,密钥必须为16字节的倍数位,否则抛异常,需要字节补全再进行加密 public static final String AES_TYPE_ECB_NO = "AES/ECB/NoPadding"; //java 不支持ZeroPadding public static final String AES_TYPE_CBC_ZERO = "AES/CBC/ZeroPadding"; //填充类型 public static final String AES_DEF_TYPE = AES_TYPE_CBC_PKCS5; //编码方式 public static final String CODE_TYPE = "UTF-8";//"GBK"; //私钥 private static final String AES_DEF_KEY = "110037d640411e09e76dd00e207d09f3";//AES固定格式为128/192/256 bits.即:16/24/32bytes。DES固定格式为128bits,即8bytes。 //偏移量 private static final String VIPARA = "1234567890123456";//CBC密钥默认偏移,可更改 private static AesUtil mAesUtil; public static AesUtil getInstance() { if (mAesUtil == null) { synchronized (AesUtil.class) { if (mAesUtil == null) { mAesUtil = new AesUtil(); } } } return mAesUtil; } /** * 加密 */ public String encrypt(String plaintext) { return encrypt(plaintext, AES_DEF_KEY); } /** * 加密 */ public String encrypt(String plaintext, String privateKey) { return encrypt(AES_DEF_TYPE, plaintext, privateKey); } /** * 加密 */ public String encrypt(String type, String plaintext, String privateKey) { //加密方式: AES128(ECB/PKCS5Padding) + Base64, 私钥:privateKey try { if (plaintext != null && plaintext.length() > 0) { byte[] cipherText; if (type != null && privateKey != null) { //两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES SecretKeySpec secretKey = new SecretKeySpec(privateKey.getBytes(), "AES"); byte[] bytes = plaintext.getBytes(CODE_TYPE); if (AES_TYPE_CBC_PKCS5.equals(type)) { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); cipherText = encrypt(type, secretKey, zeroIv, bytes); } else { cipherText = encrypt(type, secretKey, bytes); } } else { cipherText = null; } return Base64Encoder.encode(cipherText); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 解密 */ public String decrypt(String cipherTextBase64) { return decrypt(cipherTextBase64, AES_DEF_KEY); } /** * 解密 */ public String decrypt(String plaintext, String privateKey) { return decrypt(AES_DEF_TYPE, plaintext, privateKey); } /** * 解密 */ public String decrypt(String type, String plaintext, String privateKey) { try { if (plaintext != null && plaintext.length() > 0) { byte[] decrypt; if (type != null && privateKey != null) { //两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES SecretKeySpec secretKey = new SecretKeySpec(privateKey.getBytes(), "AES"); byte[] bytes = Base64Decoder.decodeToBytes(plaintext); if (AES_TYPE_CBC_PKCS5.equals(type)) { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); decrypt = decrypt(type, secretKey, zeroIv, bytes); } else { decrypt = decrypt(type, secretKey, bytes); } } else { decrypt = null; } return decrypt != null ? new String(decrypt, CODE_TYPE) : null; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 加密 */ private byte[] encrypt(String type, SecretKey key, byte[] msg) { try { Cipher c = Cipher.getInstance(type); c.init(Cipher.ENCRYPT_MODE, key); return c.doFinal(msg); } catch (Exception e) { e.printStackTrace(); } return new byte[0]; } /** * 加密 */ private byte[] encrypt(String type, SecretKey secretKey, IvParameterSpec params, byte[] msg) { try { //实例化加密类,参数为加密方式,要写全 Cipher c = Cipher.getInstance(type);//PKCS5Padding比PKCS7Padding效率高,PKCS7Padding可支持IOS加解密 //初始化,此方法可以采用三种方式,按加密算法要求来添加。 // (1)无第三个参数 // (2)第三个参数为SecureRandom random = new SecureRandom();中random对象,随机数。(AES不可采用这种方法) // (3)采用此代码中的IVParameterSpec //加密时使用:ENCRYPT_MODE; 解密时使用:DECRYPT_MODE; c.init(Cipher.ENCRYPT_MODE, secretKey, params);//CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量 //加密操作,返回加密后的字节数组,然后需要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器需要什么编码方式 return c.doFinal(msg); } catch (Exception e) { e.printStackTrace(); } return new byte[0]; } /** * 解密 */ private byte[] decrypt(String type, SecretKey secretKey, IvParameterSpec params, byte[] cipherText) { try { Cipher c = Cipher.getInstance(type); c.init(Cipher.DECRYPT_MODE, secretKey, params); return c.doFinal(cipherText); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 解密 */ private byte[] decrypt(String type, SecretKey secretKey, byte[] cipherText) { try { Cipher c = Cipher.getInstance(type); c.init(Cipher.DECRYPT_MODE, secretKey); return c.doFinal(cipherText); } catch (Exception e) { e.printStackTrace(); } return null; } }