对称加密无论是加密还是解密都使用同一个key,而非对称加密需要两个key(public key和private key)。使用public key对数据进行加密,必须使用private key对数据进行解密。

例如,有A个人。A求一个文件经过加密后传给。这时A使用了密钥生成软件生成了两个key(public key和private key), 首先A将public key通过网络发给了B,然后 B 用 public key对文件进行加密后,

将经过加密后的文件发给A,最后 A再用 private key对该文件进行解密。自始至终private key都没通过网络进行传输,因此,只要private key不泄露,即使public key和经过加密的文件都被截获,仍然无法对该文件进行解密,

因此,非对称加密较对称加密更安全。

Android SDK支持如下3种不可逆的加密算法。
1. MD5(message-digest algorithm 5,信息-摘要算法),用于加密和解密技术,常用于文件校验。不管文件多大,经过MD5后都能生成唯一的MD5值。就像现在的ISO校验,都是MD5校验。

2.  SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与 MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全。

3.  HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议)。消鉴码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。

使用一个密钥生成一个固定大小的小数据块,即 MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。

 

Android SDK支持4种加密技术:MD5、SHA、HMAC和AES。其中前3种是不可逆的加密算法。AES是可逆的加密算法。实际上,如果将Base64编码表中的字符随机打乱,也属于一种对称加密算法(Base64 编码表相当于 key),

而且是可逆加密。下面来看看如何使用上述 4 种加密算法用数据进行加密和解密。

 

MD5算法

// source参数是待加密的字符串,encrypt_MD5方法返回加密后的结果 
public String encrypt_MD5(String source) throws Exception 
{ 
   MessageDigest md5 = MessageDigest.getInstance("MD5"); 
   md5.update(source.getBytes()); 
   return Base64.encodeToString(md5.digest(), Base64.DEFAULT);}
 
 SHA算法
 public String encrypt_SHA(String source) throws Exception 
{ 
   MessageDigest sha = MessageDigest.getInstance("SHA"); 
   sha.update(source.getBytes()); 
   return Base64.encodeToString(sha.digest(), Base64.DEFAULT); 
}  
 HMAC算法
 public static String initMacKey() throws Exception 
{ 
   KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); 
   SecretKey secretKey = keyGenerator.generateKey(); 
   return Base64.encodeToString(secretKey.getEncoded(), Base64.DEFAULT); 
} 
// HMAC加密 
public static String encrypt_HMAC(String source, String key) 
 throws Exception 
{ 
   SecretKey secretKey = new SecretKeySpec(Base64.decode(key, 
     Base64.DEFAULT), "HmacMD5");   Mac mac = Mac.getInstance(secretKey.getAlgorithm()); 
   mac.init(secretKey); 
   return Base64.encodeToString(mac.doFinal(source.getBytes()), 
     Base64.DEFAULT); 
} 
// 使用HMAC算法对数据进行加密 
try 
{ 
   String key = initMacKey(); 
   String result = encrypt_HMAC("Android面试", key); 
} 
catch (Exception e) 
{ 
} AES算法
 // AES加密(126位加密,也就是16个字节) 
public String encrypt_AES(String src, String key) throws Exception 
{ 
   if (key == null) 
   { 
     Log.e("encrypt_aes_error", "Key不能为空"); 
     return null; 
   } 
   // 判断Key是否为16位 
   if (key.length() != 16) 
   { 
     Log.e("encrypt_aes_error", "Key长度不是16位"); 
     return null; 
   } 
   byte[] raw = key.getBytes(); 
   SecretKeySpec keySpec = new SecretKeySpec(raw, "AES"); 
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 算法/模式/补码方式 
   // 使用CBC模式,需要一个向量iv,可增加加密算法的强度 
   IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes()); 

   cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); 
   byte[] encrypted = cipher.doFinal(src.getBytes()); 

   return Base64.encodeToString(encrypted, Base64.DEFAULT); 
} 
// AES解密 
public String decrypt_AES(String src, String key) throws Exception 
{ 
   try 
   { 
     // 判断Key是否正确 
     if (key == null) 
     { 
       Log.e("encrypt_aes_error", "Key不能为空");      return null; 
     } 
   // 判断Key是否为16位 
   if (key.length() != 16) 
   { 
     Log.e("encrypt_aes_error", "Key长度不是16位"); 
     return null; 
   } 
   byte[] raw = key.getBytes("ASCII"); 
   SecretKeySpec keySpec = new SecretKeySpec(raw, "AES"); 
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
   IvParameterSpec iv = new IvParameterSpec( 
     "0102030405060708".getBytes()); 
   cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); 
   byte[] encrypted1 = Base64.decode(src, Base64.DEFAULT); 
   try 
   { 
     byte[] original = cipher.doFinal(encrypted1); 
     String originalString = new String(original); 
     return originalString; 
   } 
   catch (Exception e) 
   { 
     return null; 
   } 
 } 
 catch (Exception ex) 
 { 
   return null;}
}