Android传输数据时Aes加密解密详解
一、AES加密算法
AES是一种“对称加密算法”。用来替代原先的DES。
动态密钥:长度不能小于16位字节。
二、AES加密算法实例
注:加密之后要进行Base64编码之后进行传输
解密之前要进行Base64解码之后进行解密
1. 设置常量
private final static String HEX = "0123456789ABCDEF"; /** AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式*/ private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding"; /** AES 加密*/ private static final String AES = "AES"; /** SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法*/ private static final String SHA1PRNG="SHA1PRNG"; |
2. 动态生成密钥:加密和解密使用同一个密钥
//二进制转字符 public static String byte2String(byte[] byt) { if (byt == null) return ""; StringBuffer result = new StringBuffer(2 * byt.length); for (int i = 0; i < byt.length; i++) { appendHex(result, byt[i]); } return result.toString(); } private static void appendHex(StringBuffer sb, byte b) { sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } /* * 生成随机数,可以当做动态的密钥 加密和解密的密钥必须一致,不然将不能解密 */ public static String generateKey() { try { SecureRandom localSecureRandom = SecureRandom.getInstance(SHA1PRNG); byte[] bytes_key = new byte[20]; localSecureRandom.nextBytes(bytes_key); String str_key = byte2String(bytes_key); return str_key; } catch (Exception e) { e.printStackTrace(); } return null; } |
3. 处理密钥Key
// 对密钥进行处理 private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance(AES); //for android SecureRandom sr = null; // 在4.2以上版本中,SecureRandom获取方式发生了改变 if (android.os.Build.VERSION.SDK_INT >= 17) { sr = SecureRandom.getInstance(SHA1PRNG, "Crypto"); } else { sr = SecureRandom.getInstance(SHA1PRNG); } // for Java // secureRandom = SecureRandom.getInstance(SHA1PRNG); sr.setSeed(seed); kgen.init(128, sr); //256 bits or 128 bits,192bits //AES中128位密钥版本有10个加密循环,192比特密钥版本有12个加密循环,256比特密钥版本则有14个加密循环。 SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } |
4. 加密实现
/* * 加密 */ public static String encrypt(String key, String cleartext) { if (TextUtils.isEmpty(cleartext)) { return cleartext; } try { byte[] result = encrypt(key, cleartext.getBytes()); return Base64.encodeToString(result,Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } /* * 加密 */ private static byte[] encrypt(String key, byte[] clear) throws Exception { byte[] raw = getRawKey(key.getBytes()); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] encrypted = cipher.doFinal(clear); return encrypted; } |
5. 解密实现
/* * 解密 */ public static String decrypt(String key, String encrypted) { if (TextUtils.isEmpty(encrypted)) { return encrypted; } try { byte[] enc = Base64.decode(encrypted,Base64.DEFAULT); byte[] result = decrypt(key, enc); return new String(result); } catch (Exception e) { e.printStackTrace(); } return null; } /* * 解密 */ private static byte[] decrypt(String key, byte[] encrypted) throws Exception { byte[] raw = getRawKey(key.getBytes()); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } |
6. 加密解密方式实现
//生成AES密钥 String strKey = generateKey(); //AES加密 String strEncode = encrypt(strKey,"Lking"); Log.e("Lking","AES加密---->"+strEncode); //AES解密 String strDecode = decrypt(strKey,strEncode); Log.e("Lking","AES解密---->"+strDecode); |