1 package com.powercreator.cms.util; 2 3 import java.security.SecureRandom; 4 import javax.crypto.Cipher; 5 import javax.crypto.KeyGenerator; 6 import javax.crypto.SecretKey; 7 import javax.crypto.spec.IvParameterSpec; 8 import javax.crypto.spec.SecretKeySpec; 9 /** 10 * @author vijoz 11 * @version 创建时间:2016-6-30 12 */ 13 public class AESUtils { 14 public static final String TAG = "AESUtils"; 15 16 public static String encrypt(String seed, String clearText) { 17 // Log.d(TAG, "加密前的seed=" + seed + ",内容为:" + clearText); 18 byte[] result = null; 19 try { 20 byte[] rawkey = getRawKey(seed.getBytes()); 21 result = encrypt(rawkey, clearText.getBytes()); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 String content = toHex(result); 26 // Log.d(TAG, "加密后的内容为:" + content); 27 return content; 28 } 29 30 public static String decrypt(String seed, String encrypted) { 31 // Log.d(TAG, "解密前的seed=" + seed + ",内容为:" + encrypted); 32 byte[] rawKey; 33 try { 34 rawKey = getRawKey(seed.getBytes()); 35 byte[] enc = toByte(encrypted); 36 byte[] result = decrypt(rawKey, enc); 37 String coentn = new String(result); 38 // Log.d(TAG, "解密后的内容为:" + coentn); 39 return coentn; 40 } catch (Exception e) { 41 e.printStackTrace(); 42 return null; 43 } 44 45 } 46 47 private static byte[] getRawKey(byte[] seed) throws Exception { 48 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 49 SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 50 sr.setSeed(seed); 51 kgen.init(128, sr); 52 SecretKey sKey = kgen.generateKey(); 53 byte[] raw = sKey.getEncoded(); 54 return raw; 55 } 56 57 private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { 58 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 59 // Cipher cipher = Cipher.getInstance("AES"); 60 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 61 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec( 62 new byte[cipher.getBlockSize()])); 63 byte[] encrypted = cipher.doFinal(clear); 64 return encrypted; 65 } 66 67 private static byte[] decrypt(byte[] raw, byte[] encrypted) 68 throws Exception { 69 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 70 // Cipher cipher = Cipher.getInstance("AES"); 71 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 72 cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec( 73 new byte[cipher.getBlockSize()])); 74 byte[] decrypted = cipher.doFinal(encrypted); 75 return decrypted; 76 } 77 78 public static String toHex(String txt) { 79 return toHex(txt.getBytes()); 80 } 81 82 public static String fromHex(String hex) { 83 return new String(toByte(hex)); 84 } 85 86 public static byte[] toByte(String hexString) { 87 int len = hexString.length() / 2; 88 byte[] result = new byte[len]; 89 for (int i = 0; i < len; i++) 90 result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 91 16).byteValue(); 92 return result; 93 } 94 95 public static String toHex(byte[] buf) { 96 if (buf == null) 97 return ""; 98 StringBuffer result = new StringBuffer(2 * buf.length); 99 for (int i = 0; i < buf.length; i++) { 100 appendHex(result, buf[i]); 101 } 102 return result.toString(); 103 } 104 105 private static void appendHex(StringBuffer sb, byte b) { 106 final String HEX = "0123456789ABCDEF"; 107 sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); 108 } 109 }
上面的实现貌似有些问题,待调试!
下面是转发的另一个实现:
1 import java.io.UnsupportedEncodingException; 2 import java.security.InvalidKeyException; 3 import java.security.Key; 4 import java.security.NoSuchAlgorithmException; 5 import javax.crypto.BadPaddingException; 6 import javax.crypto.Cipher; 7 import javax.crypto.IllegalBlockSizeException; 8 import javax.crypto.KeyGenerator; 9 import javax.crypto.NoSuchPaddingException; 10 import javax.crypto.spec.SecretKeySpec; 11 12 public class AES { 13 14 static final String algorithmStr = "AES/ECB/PKCS5Padding"; 15 16 private static final Object TAG = "AES"; 17 18 static private KeyGenerator keyGen; 19 20 static private Cipher cipher; 21 22 static boolean isInited = false; 23 24 private static void init() { 25 try { 26 /**为指定算法生成一个 KeyGenerator 对象。 27 *此类提供(对称)密钥生成器的功能。 28 *密钥生成器是使用此类的某个 getInstance 类方法构造的。 29 *KeyGenerator 对象可重复使用,也就是说,在生成密钥后, 30 *可以重复使用同一 KeyGenerator 对象来生成进一步的密钥。 31 *生成密钥的方式有两种:与算法无关的方式,以及特定于算法的方式。 32 *两者之间的惟一不同是对象的初始化: 33 *与算法无关的初始化 34 *所有密钥生成器都具有密钥长度 和随机源 的概念。 35 *此 KeyGenerator 类中有一个 init 方法,它可采用这两个通用概念的参数。 36 *还有一个只带 keysize 参数的 init 方法, 37 *它使用具有最高优先级的提供程序的 SecureRandom 实现作为随机源 38 *(如果安装的提供程序都不提供 SecureRandom 实现,则使用系统提供的随机源)。 39 *此 KeyGenerator 类还提供一个只带随机源参数的 inti 方法。 40 *因为调用上述与算法无关的 init 方法时未指定其他参数, 41 *所以由提供程序决定如何处理将与每个密钥相关的特定于算法的参数(如果有)。 42 *特定于算法的初始化 43 *在已经存在特定于算法的参数集的情况下, 44 *有两个具有 AlgorithmParameterSpec 参数的 init 方法。 45 *其中一个方法还有一个 SecureRandom 参数, 46 *而另一个方法将已安装的高优先级提供程序的 SecureRandom 实现用作随机源 47 *(或者作为系统提供的随机源,如果安装的提供程序都不提供 SecureRandom 实现)。 48 *如果客户端没有显式地初始化 KeyGenerator(通过调用 init 方法), 49 *每个提供程序必须提供(和记录)默认初始化。 50 */ 51 keyGen = KeyGenerator.getInstance("AES"); 52 } catch (NoSuchAlgorithmException e) { 53 e.printStackTrace(); 54 } 55 // 初始化此密钥生成器,使其具有确定的密钥长度。 56 keyGen.init(128); //128位的AES加密 57 try { 58 // 生成一个实现指定转换的 Cipher 对象。 59 cipher = Cipher.getInstance(algorithmStr); 60 } catch (NoSuchAlgorithmException e) { 61 e.printStackTrace(); 62 } catch (NoSuchPaddingException e) { 63 e.printStackTrace(); 64 } 65 //标识已经初始化过了的字段 66 isInited = true; 67 } 68 69 private static byte[] genKey() { 70 if (!isInited) { 71 init(); 72 } 73 //首先 生成一个密钥(SecretKey), 74 //然后,通过这个秘钥,返回基本编码格式的密钥,如果此密钥不支持编码,则返回 null。 75 return keyGen.generateKey().getEncoded(); 76 } 77 78 private static byte[] encrypt(byte[] content, byte[] keyBytes) { 79 byte[] encryptedText = null; 80 if (!isInited) { 81 init(); 82 } 83 /** 84 *类 SecretKeySpec 85 *可以使用此类来根据一个字节数组构造一个 SecretKey, 86 *而无须通过一个(基于 provider 的)SecretKeyFactory。 87 *此类仅对能表示为一个字节数组并且没有任何与之相关联的钥参数的原始密钥有用 88 *构造方法根据给定的字节数组构造一个密钥。 89 *此构造方法不检查给定的字节数组是否指定了一个算法的密钥。 90 */ 91 Key key = new SecretKeySpec(keyBytes, "AES"); 92 try { 93 // 用密钥初始化此 cipher。 94 cipher.init(Cipher.ENCRYPT_MODE, key); 95 } catch (InvalidKeyException e) { 96 e.printStackTrace(); 97 } 98 try { 99 //按单部分操作加密或解密数据,或者结束一个多部分操作。(不知道神马意思) 100 encryptedText = cipher.doFinal(content); 101 } catch (IllegalBlockSizeException e) { 102 e.printStackTrace(); 103 } catch (BadPaddingException e) { 104 e.printStackTrace(); 105 } 106 return encryptedText; 107 } 108 109 private static byte[] encrypt(String content, String password) { 110 try { 111 byte[] keyStr = getKey(password); 112 SecretKeySpec key = new SecretKeySpec(keyStr, "AES"); 113 Cipher cipher = Cipher.getInstance(algorithmStr);//algorithmStr 114 byte[] byteContent = content.getBytes("utf-8"); 115 cipher.init(Cipher.ENCRYPT_MODE, key);// ʼ 116 byte[] result = cipher.doFinal(byteContent); 117 return result; // 118 } catch (NoSuchAlgorithmException e) { 119 e.printStackTrace(); 120 } catch (NoSuchPaddingException e) { 121 e.printStackTrace(); 122 } catch (InvalidKeyException e) { 123 e.printStackTrace(); 124 } catch (UnsupportedEncodingException e) { 125 e.printStackTrace(); 126 } catch (IllegalBlockSizeException e) { 127 e.printStackTrace(); 128 } catch (BadPaddingException e) { 129 e.printStackTrace(); 130 } 131 return null; 132 } 133 134 private static byte[] decrypt(byte[] content, String password) { 135 try { 136 byte[] keyStr = getKey(password); 137 SecretKeySpec key = new SecretKeySpec(keyStr, "AES"); 138 Cipher cipher = Cipher.getInstance(algorithmStr);//algorithmStr 139 cipher.init(Cipher.DECRYPT_MODE, key);// ʼ 140 byte[] result = cipher.doFinal(content); 141 return result; // 142 } catch (NoSuchAlgorithmException e) { 143 e.printStackTrace(); 144 } catch (NoSuchPaddingException e) { 145 e.printStackTrace(); 146 } catch (InvalidKeyException e) { 147 e.printStackTrace(); 148 } catch (IllegalBlockSizeException e) { 149 e.printStackTrace(); 150 } catch (BadPaddingException e) { 151 e.printStackTrace(); 152 } 153 return null; 154 } 155 156 private static byte[] getKey(String password) { 157 byte[] rByte = null; 158 if (password!=null) { 159 rByte = password.getBytes(); 160 }else{ 161 rByte = new byte[24]; 162 } 163 return rByte; 164 } 165 166 /** 167 * 将二进制转换成16进制 168 * @param buf 169 * @return 170 */ 171 public static String parseByte2HexStr(byte buf[]) { 172 StringBuffer sb = new StringBuffer(); 173 for (int i = 0; i < buf.length; i++) { 174 String hex = Integer.toHexString(buf[i] & 0xFF); 175 if (hex.length() == 1) { 176 hex = '0' + hex; 177 } 178 sb.append(hex.toUpperCase()); 179 } 180 return sb.toString(); 181 } 182 183 /** 184 * 将16进制转换为二进制 185 * @param hexStr 186 * @return 187 */ 188 public static byte[] parseHexStr2Byte(String hexStr) { 189 if (hexStr.length() < 1) 190 return null; 191 byte[] result = new byte[hexStr.length() / 2]; 192 for (int i = 0; i < hexStr.length() / 2; i++) { 193 int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); 194 int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 195 16); 196 result[i] = (byte) (high * 16 + low); 197 } 198 return result; 199 } 200 201 //注意: 这里的password(秘钥必须是16位的) 202 private static final String keyBytes = "abcdefgabcdefg12"; 203 204 /** 205 *加密 206 */ 207 public static String encode(String content){ 208 //加密之后的字节数组,转成16进制的字符串形式输出 209 return parseByte2HexStr(encrypt(content, keyBytes)); 210 } 211 212 /** 213 *解密 214 */ 215 public static String decode(String content){ 216 //解密之前,先将输入的字符串按照16进制转成二进制的字节数组,作为待解密的内容输入 217 byte[] b = decrypt(parseHexStr2Byte(content), keyBytes); 218 return new String(b); 219 } 220 221 //测试用例 222 public static void test1(){ 223 String content = "hello abcdefggsdfasdfasdf"; 224 String pStr = encode(content ); 225 System.out.println("加密前:"+content); 226 System.out.println("加密后:" + pStr); 227 228 String postStr = decode(pStr); 229 System.out.println("解密后:"+ postStr ); 230 } 231 232 public static void main(String[] args) { 233 test1(); 234 } 235 }
第三个,说实测兼容所有版本的:
1 import android.annotation.SuppressLint; 2 import java.security.SecureRandom; 3 4 import javax.crypto.Cipher; 5 import javax.crypto.KeyGenerator; 6 import javax.crypto.SecretKey; 7 import javax.crypto.spec.IvParameterSpec; 8 import javax.crypto.spec.SecretKeySpec; 9 10 /** 11 * 12 * 13 * Author:sunger 14 */ 15 public class AESUtils { 16 17 public static String encrypt(String seed, String cleartext) 18 throws Exception { 19 20 byte[] rawKey = getRawKey(seed.getBytes()); 21 22 byte[] result = encrypt(rawKey, cleartext.getBytes()); 23 24 return toHex(result); 25 26 } 27 28 public static String decrypt(String seed, String encrypted) 29 throws Exception { 30 31 byte[] rawKey = getRawKey(seed.getBytes()); 32 33 byte[] enc = toByte(encrypted); 34 35 byte[] result = decrypt(rawKey, enc); 36 37 return new String(result); 38 39 } 40 41 @SuppressLint("TrulyRandom") 42 private static byte[] getRawKey(byte[] seed) throws Exception { 43 44 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 45 46 SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); 47 48 sr.setSeed(seed); 49 50 kgen.init(128, sr); // 192 and 256 bits may not be available 51 52 SecretKey skey = kgen.generateKey(); 53 54 byte[] raw = skey.getEncoded(); 55 56 return raw; 57 58 } 59 60 private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { 61 62 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 63 64 Cipher cipher = Cipher.getInstance("AES"); 65 66 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec( 67 new byte[cipher.getBlockSize()])); 68 69 byte[] encrypted = cipher.doFinal(clear); 70 71 return encrypted; 72 73 } 74 75 private static byte[] decrypt(byte[] raw, byte[] encrypted) 76 throws Exception { 77 78 SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 79 80 Cipher cipher = Cipher.getInstance("AES"); 81 82 cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec( 83 new byte[cipher.getBlockSize()])); 84 85 byte[] decrypted = cipher.doFinal(encrypted); 86 87 return decrypted; 88 89 } 90 91 private static byte[] toByte(String hexString) { 92 93 int len = hexString.length() / 2; 94 95 byte[] result = new byte[len]; 96 97 for (int i = 0; i < len; i++) 98 99 result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 100 16).byteValue(); 101 102 return result; 103 104 } 105 106 private static String toHex(byte[] buf) { 107 108 if (buf == null) 109 110 return ""; 111 112 StringBuffer result = new StringBuffer(2 * buf.length); 113 114 for (int i = 0; i < buf.length; i++) { 115 116 appendHex(result, buf[i]); 117 118 } 119 120 return result.toString(); 121 122 } 123 124 private final static String HEX = "0123456789ABCDEF"; 125 126 private static void appendHex(StringBuffer sb, byte b) { 127 128 sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); 129 130 } 131 132 }
相关连接:http://blog.csdn.net/xinzheng_wang/article/details/9159969
http://blog.csdn.net/randyjiawenjie/article/details/6587986
http://blog.csdn.net/wuchuanpingstone/article/details/6715196