0、概述
在項目開發中,我們常需要用到加解密算法,加解密算法主要分爲三大類:
1、對稱加密算法,如:AES、DES、3DES
2、非對稱加密算法,如:RSA、DSA、ECC
3、散列算法,如:MD5、SHA1、HMAC
1、各算法對比
不廢話,直接開表格對比:
對稱加密算法(加解密密鑰相同)
名稱 |
密鑰長度 |
運算速度 |
安全性 |
資源消耗 |
DES |
56位 |
較快 |
低 |
中 |
3DES |
112位或168位 |
慢 |
中 |
高 |
AES |
128、192、256位 |
快 |
高 |
低 |
非對稱算法(加密密鑰和解密密鑰不同)
名稱 |
成熟度 |
安全性(取決於密鑰長度) |
運算速度 |
資源消耗 |
RSA |
高 |
高 |
慢 |
高 |
DSA |
高 |
高 |
慢 |
只能用於數字簽名 |
ECC |
低 |
高 |
快 |
低(計算量小,存儲空間佔用小,帶寬要求低) |
散列算法比較
名稱 |
安全性 |
速度 |
SHA-1 |
高 |
慢 |
MD5 |
中 |
快 |
對稱與非對稱算法比較
名稱 |
密鑰管理 |
安全性 |
速度 |
對稱算法 |
比較難,不適合互聯網,一般用於內部系統 |
中 |
快好幾個數量級(軟件加解密速度至少快100倍,每秒可以加解密數M比特數據),適合大數據量的加解密處理 |
非對稱算法 |
密鑰容易管理 |
高 |
慢,適合小數據量加解密或數據簽名 |
3、項目中常用總結
對稱加密: AES(128位),
非對稱加密: ECC(160位)或RSA(1024),
消息摘要: MD5
數字簽名:DSA
其中,AES和MD5最爲常用,
4、代碼示例
下面直接實現一個包含AES和MD5的加解密類,不廢話,直接上步驟:
1、添加第三方包的依賴:項目用到兩個第三方包,在pom中添加這兩個包的依賴:
<!-- 添加加解密算法的依賴 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.8</version>
</dependency>
2、import相關包;
3、AES有五種模式(ECB、CBC、CFB、OFB、CTR),我們採用的是CBC,各工作模式的遠離自行百度,好了,直接上代碼:
package com.anson.utility;
//引入相關包
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
//引入第三方包
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
public class Encrypt {
//--------------AES---------------
private static final String KEY = "f4k9f5w7f8g4er26"; // 密匙,必須16位
private static final String OFFSET = "5e8y6w45ju8w9jq8"; // 偏移量
private static final String ENCODING = "UTF-8"; // 編碼
private static final String ALGORITHM = "AES"; //算法
private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; // 默認的加密算法,CBC模式
//---------------MD5-------------------
private static final String MD5KEY = "f4k9f5w7f8g4er26"; // 密匙
/**
* AES加密
* @param data
* @return String
* @author anson
* @date 2019-8-24 18:43:07
*/
public static String AESencrypt(String data) throws Exception
{
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes());//CBC模式偏移量IV
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(data.getBytes(ENCODING));
return new Base64().encodeToString(encrypted);//加密後再使用BASE64做轉碼
}
/**
* AES解密
* @param data
* @return String
* @author anson
* @date 2019-8-24 18:46:07
*/
public static String AESdecrypt(String data) throws Exception
{
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes()); //CBC模式偏移量IV
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] buffer = new Base64().decode(data);//先用base64解碼
byte[] encrypted = cipher.doFinal(buffer);
return new String(encrypted, ENCODING);
}
//---------------------MD5--------------------
/**
* MD5方法
* @param text 明文
* @return 密文
* @author anson
* @date 2019-8-24 18:54:42
*/
public static String MD5encrypt(String text) throws Exception {
//加密後的字符串
String encodeStr=DigestUtils.md5Hex(text + MD5KEY);
return encodeStr;
}
/**
* MD5驗證方法
* @param text 明文
* @param md5 密文
* @return true/false
* @author anson
* @date 2019-8-24 18:58:56
*/
public static boolean verify(String text, String md5) throws Exception
{
//根據傳入的密鑰進行驗證
String md5Text = MD5encrypt(text);
if(md5Text.equalsIgnoreCase(md5))
{
return true;
}
return false;
}
}