工作中常用的五種加密算法
最近,項(xiàng)目中做了一些安全性要求的整改。而加密是使用過(guò)程中常用的手段之一。這里簡(jiǎn)單的整理下,希望對(duì)小伙伴有幫助。
使用場(chǎng)景
加密是一種將原始信息(明文)轉(zhuǎn)換成難以被直接理解的形式(密文)的過(guò)程,
其主要目的是為了保護(hù)信息的安全和隱私。主要應(yīng)用于以下場(chǎng)景:
- 數(shù)據(jù)保密:防止未經(jīng)授權(quán)的個(gè)人身份信息和敏感數(shù)據(jù)。保護(hù)個(gè)人隱私、商業(yè)機(jī)密和國(guó)家機(jī)密。如:公司內(nèi)部文件、云存儲(chǔ)信息防截獲。
- 數(shù)據(jù)完整性:確保數(shù)據(jù)在傳輸或存儲(chǔ)過(guò)程中未被篡改。如:軟件下載、銀行轉(zhuǎn)賬等。
- 身份驗(yàn)證:驗(yàn)證通信雙方的身份,確保數(shù)據(jù)是從一個(gè)可信的來(lái)源發(fā)送的,并且在整個(gè)傳輸過(guò)程中沒(méi)有被攔截或篡改。如:用戶(hù)登錄、電子郵件認(rèn)證等。
- 數(shù)據(jù)訪問(wèn)控制:加密可以限制對(duì)數(shù)據(jù)的訪問(wèn),只有擁有正確密鑰的用戶(hù)才能解密和訪問(wèn)數(shù)據(jù)。如:企業(yè)VPN等。
- 網(wǎng)絡(luò)安全:在互聯(lián)網(wǎng)上傳輸數(shù)據(jù)時(shí),加密可以防止中間人攻擊和其他網(wǎng)絡(luò)攻擊,確保數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸安全。如:SSL/TLS協(xié)議等。
- 金融交易安全:在電子商務(wù)和在線銀行中,加密用于保護(hù)交易數(shù)據(jù),防止信用卡欺詐和其他金融犯罪。如:在線支付(金融機(jī)構(gòu)提供的RSA簽名和證書(shū))等。
常用加密算法
1.MD5 加密
(1) 適用場(chǎng)景
MD5 作為一種廣泛使用的哈希函數(shù),主要用于以下場(chǎng)景:
- 數(shù)據(jù)完整性校驗(yàn):驗(yàn)證文件傳輸過(guò)程中是否被篡改。
- 數(shù)字簽名:確保信息傳輸?shù)耐暾院蛠?lái)源的真實(shí)性。
- 密碼存儲(chǔ):在數(shù)據(jù)庫(kù)中存儲(chǔ)用戶(hù)密碼的哈希值,而非明文。
(2) 功能特性
- 長(zhǎng)度固定:無(wú)論輸入長(zhǎng)度如何,輸出都是128位(16字節(jié))的哈希值。
- 快速計(jì)算:MD5 算法計(jì)算速度快,適用于大量數(shù)據(jù)的哈希處理。
- 不可逆性:MD5 加密是不可逆的,因此通常只有加密過(guò)程,而沒(méi)有解密過(guò)程
(3) 原理及流程圖
MD5 算法將輸入的消息經(jīng)過(guò)填充、分段、循環(huán)處理等步驟,最終生成一個(gè)128位的哈希值。
用字符串"Hello"的加密過(guò)程說(shuō)明 MD5 算法的基本處理流程:
1. 原始輸入(明文)
|
|(轉(zhuǎn)換為二進(jìn)制)
V
2. 二進(jìn)制數(shù)據(jù) "Hello"
|
|(填充到512位的倍數(shù))
V
3. 填充后的二進(jìn)制數(shù)據(jù)
|
|(添加原始長(zhǎng)度的64位表示)
V
4. 長(zhǎng)度附加后的二進(jìn)制數(shù)據(jù)
|
|(分割成512位的消息塊)
V
5. 消息塊1 ... 消息塊n
|
|(每塊512位,共16個(gè)32位字)
V
6. 初始MD5值(ABCD)
|
|(通過(guò)主循環(huán)處理每個(gè)塊)
V
7. 主循環(huán)(每塊16步)
|_________|_________|
| | |
V V V
8. 經(jīng)過(guò)F, G, H, I函數(shù)的32位字
|_________|_________|
| | |
V V V
9. 更新后的MD5值
|
V
10. 最終MD5散列值(128位)
(4) 代碼實(shí)現(xiàn)
使用 Java 實(shí)現(xiàn) MD5 加密的示例代碼:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Example {
//用于將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制表示的字符串
public static String toHexString(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static String getMD5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
return toHexString(messageDigest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String password = "Hello, World!";
//輸出結(jié)果:65a8e27d8879283831b664bd8b7f0ad4
System.out.println("MD5 Hash: " + getMD5(password));
}
}
(5) 注意事項(xiàng)
- MD5 算法已經(jīng)不再被認(rèn)為是安全的,因此不推薦用于需要高安全性的加密場(chǎng)景。
- MD5 算法的輸出可以作為數(shù)據(jù)完整性校驗(yàn),但不應(yīng)用于加密和解密操作。
2.AES 加密
(1) 適用場(chǎng)景
AES(高級(jí)加密標(biāo)準(zhǔn))是一種廣泛使用的對(duì)稱(chēng)加密算法,適用于以下場(chǎng)景:
- 數(shù)據(jù)傳輸安全:在網(wǎng)絡(luò)通信中加密數(shù)據(jù),保護(hù)數(shù)據(jù)傳輸過(guò)程中的隱私和完整性。
- 文件和數(shù)據(jù)存儲(chǔ):對(duì)存儲(chǔ)在服務(wù)器或云端的敏感文件進(jìn)行加密。
- VPN 連接:確保遠(yuǎn)程連接的安全性。
(2) 功能特性
- 安全性:AES 提供強(qiáng)大的安全性,是目前最推薦使用的對(duì)稱(chēng)加密算法之一。
- 靈活性:支持128、192和256位的密鑰長(zhǎng)度,適應(yīng)不同的安全級(jí)別需求。
- 效率高:AES算法效率高,適合大量數(shù)據(jù)的快速加密。
(3) 原理及流程圖
例如,使用AES加密算法加密字符串 "hello"
1. 明文 "hello"
|
|(轉(zhuǎn)換為二進(jìn)制格式)
V
2. 128位二進(jìn)制明文
|
|(可能需要填充)
V
3. 填充后的128位二進(jìn)制數(shù)據(jù)
|
|(密鑰擴(kuò)展)
V
4. 生成輪密鑰
|
|(初始輪密鑰加)
V
5. 與輪密鑰異或后的數(shù)據(jù)塊
|
|(主輪加密處理)
V
|_________________________|
| |
| SubBytes(字節(jié)代換) |
|_________________________|
| |
| ShiftRows(行移位) |
|_________________________|
| |
| MixColumns (列混淆) |
|_________________________|
| |
| AddRoundKey(輪密鑰加) |
|_________________________|
V V
6. 密文數(shù)據(jù)塊
|
V
7. 密文(二進(jìn)制格式)
(4) 示例代碼
對(duì)字符串 "hello" 進(jìn)行AES加密的示例:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
public class AESExample {
public static void main(String[] args) {
try {
// 實(shí)例化密鑰生成器,并初始化為AES(128位)
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
// 初始化128位 ,可修改
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
// 實(shí)例化Cipher對(duì)象,用于AES加密
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// 轉(zhuǎn)換明文字符串 "hello" 為二進(jìn)制數(shù)據(jù)
String plainText = "hello";
byte[] plainTextBytes = plainText.getBytes();
// 加密得到密文
byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
// 打印加密后的密文(通常以十六進(jìn)制形式表示)
System.out.println("Encrypted bytes: " + bytesToHex(encryptedBytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
// 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}
(5) 注意事項(xiàng)
- AES加密是對(duì)稱(chēng)加密,加密和解密使用相同的密鑰。
- 密鑰長(zhǎng)度的選擇需要根據(jù)具體的應(yīng)用場(chǎng)景和安全需求來(lái)確定。
3.DES加密
(1) 適用場(chǎng)景
DES(數(shù)據(jù)加密標(biāo)準(zhǔn))是一種較早的對(duì)稱(chēng)加密算法,由于密鑰長(zhǎng)度(56位有效密鑰,相對(duì)較短),其安全性相對(duì)較低,一般一些舊的系統(tǒng)中仍然使用。
主要適用場(chǎng)景包括:
數(shù)據(jù)傳輸:在安全性要求不是特別高的場(chǎng)合,DES仍可用于數(shù)據(jù)傳輸?shù)募用堋?/p>
(2) 功能特性
- 對(duì)稱(chēng)加密:使用相同的密鑰進(jìn)行加密和解密。
- 密鑰長(zhǎng)度:實(shí)際有效的密鑰長(zhǎng)度為56位,另外8位用于奇偶性校驗(yàn)。
- 效率:由于算法較老,在現(xiàn)代硬件上的相對(duì)速度較慢。
- 安全性:由于密鑰長(zhǎng)度較短,DES容易受到暴力破解攻擊,因此認(rèn)為不安全的。
(3) 原理及流程圖
我們通過(guò)以下步驟使用DES加密字符串 "hello":
1. 明文 "hello"
|
|(轉(zhuǎn)換為二進(jìn)制并填充)
V
2. 64位二進(jìn)制明文
|
|(初始置換 IP)
V
3. 初始置換后的數(shù)據(jù)塊
|
|(密鑰加)
V
4. 與密鑰異或后的數(shù)據(jù)塊
|
|(Feistel網(wǎng)絡(luò)處理)
V
|_________________________|
| |
| 密鑰加 |
|_________________________|
| |
| 置換 |
|_________________________|
| |
| 代換 |
|_________________________|
| |
| 循環(huán)左移 |
|_________________________|
V V
5. Feistel網(wǎng)絡(luò)輸出
|
|(逆置換 IP^-1)
V
6. 逆置換后的密文塊
|
V
7. 密文
(4) 示例代碼(Java)
以下是使用Java代碼對(duì)字符串 "hello" 進(jìn)行DES加密的示例:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class DESExample {
public static void main(String[] args) {
try {
// 實(shí)例化密鑰生成器,并初始化為DES
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
keyGenerator.init(56); // DES密鑰長(zhǎng)度為56位
SecretKey secretKey = keyGenerator.generateKey();
// 實(shí)例化Cipher對(duì)象,用于DES加密
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(new byte[8]); // 使用8位的IV
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
// 轉(zhuǎn)換明文字符串 "hello" 為二進(jìn)制數(shù)據(jù)
String plainText = "hello";
byte[] plainTextBytes = plainText.getBytes("UTF-8");
// 加密得到密文
byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
// 打印加密后的密文(通常以Base64形式表示)
System.out.println("Encrypted text: " + Base64.getEncoder().encodeToString(encryptedBytes));
} catch (Exception e) {
e.printStackTrace();
}
}
}
(5) 注意事項(xiàng)
- DES由于其較短的密鑰長(zhǎng)度,已不適用于安全性要求高的場(chǎng)合。
- 在實(shí)際使用中,推薦使用AES或其他更安全的加密算法。
4.國(guó)密算法加密
(1) 適用場(chǎng)景
國(guó)密算法,即中國(guó)國(guó)家商用密碼算法標(biāo)準(zhǔn),包括但不限于SM1、SM2、SM3、SM4等。主要用于:
- 金融服務(wù):在金融服務(wù)行業(yè)中用于保證交易安全。
- 政府通信:確保政府?dāng)?shù)據(jù)傳輸?shù)陌踩浴?/li>
- 企業(yè)數(shù)據(jù)保護(hù):用于保護(hù)商業(yè)機(jī)密和客戶(hù)數(shù)據(jù)。
- 安全令牌:用于安全令牌的加密。
(2) 功能特性
- 標(biāo)準(zhǔn)性:國(guó)密算法符合中國(guó)的商用密碼標(biāo)準(zhǔn)。
- 安全性:可抵御多種已知攻擊方式。
- 多樣性:包含多種算法,如SM2用于數(shù)字簽名,SM4用于數(shù)據(jù)加密。
(3) 原理及流程圖
使用字符串 "hello" 進(jìn)行說(shuō)明:
1. 明文 "hello"
|
|(轉(zhuǎn)換為二進(jìn)制格式)
V
2. 二進(jìn)制明文數(shù)據(jù)
|
|(配置密鑰和參數(shù))
V
3. 初始化加密模塊
|
|(設(shè)置SM4密鑰和IV)
V
4. 使用SM4加密明文
|
|(多輪迭代加密處理)
V
5. 輸出SM4密文
(4) 示例代碼(Java)
使用Java偽代碼對(duì)字符串 "hello" 進(jìn)行SM4加密的示例:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
public class SM4Example {
public static void main(String[] args) {
try {
// 添加Bouncy Castle安全提供者
Security.addProvider(new BouncyCastleProvider());
// 實(shí)例化密鑰生成器,并初始化為SM4
KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4");
keyGenerator.init(128); // SM4密鑰長(zhǎng)度為128位
SecretKey secretKey = keyGenerator.generateKey();
// 實(shí)例化Cipher對(duì)象,用于SM4加密
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding");
IvParameterSpec iv = new IvParameterSpec(new byte[16]); // 16字節(jié)的IV
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
// 轉(zhuǎn)換明文字符串 "hello" 為二進(jìn)制數(shù)據(jù)
String plainText = "hello";
byte[] plainTextBytes = plainText.getBytes("UTF-8");
// 加密得到密文
byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
// 打印加密后的密文(通常以十六進(jìn)制或Base64形式表示)
System.out.println("Encrypted text: " + bytesToHex(encryptedBytes));
} catch (Exception e) {
e.printStackTrace();
}
}
// 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}
(5) 注意事項(xiàng)
- 密鑰管理是加密過(guò)程中的一個(gè)重要環(huán)節(jié),密鑰應(yīng)該安全地生成、存儲(chǔ)和分發(fā)。
- 國(guó)密算法的使用需要遵守相關(guān)的法律法規(guī)和標(biāo)準(zhǔn)。
5. RSA 加密
(1) 適用場(chǎng)景
使用場(chǎng)景:
- 安全電子郵件:使用 RSA 對(duì)郵件內(nèi)容進(jìn)行加密,確保郵件傳輸過(guò)程中的安全性。
- SSL/TLS:在 SSL/TLS 協(xié)議中,RSA 用于加密交換對(duì)稱(chēng)密鑰,以建立安全通信。
- 數(shù)字簽名:RSA 用于生成數(shù)字簽名,驗(yàn)證軟件或文檔的完整性和來(lái)源。
- 身份驗(yàn)證:用于身份驗(yàn)證過(guò)程,確保通信雙方的身份。
(2) 功能特性
- 非對(duì)稱(chēng)加密:使用一對(duì)密鑰,公鑰加密,私鑰解密。
- 安全性:難以破解,安全性高。
- 密鑰長(zhǎng)度:通常使用 1024 位、2048 位或更長(zhǎng)的密鑰,以提高安全性。
(3) 原理及流程圖
例如,明文"hello"加密解密過(guò)程如下:
1. 明文 "hello"
|
|(轉(zhuǎn)換為數(shù)值 m)
V
2. 使用公鑰 (e, n) 加密
|___________|
| |
| m^e mod n|
|___________|
|
V
3. 得到密文 c
|
|(使用私鑰 (d, n) 解密)
V
|___________|
| |
| c^d mod n|
|___________|
|
V
4. 恢復(fù)明文 m
|
V
5. 明文 "hello"
(4) 程序?qū)崿F(xiàn)
使用Java實(shí)現(xiàn)RSA加密和解密的簡(jiǎn)單示例:
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAExample {
public static void main(String[] args) throws Exception {
// 生成密鑰對(duì)
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 公鑰和私鑰
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 明文
String plainText = "hello";
byte[] data = plainText.getBytes();
// 加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data);
System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encryptedData));
// 解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
String decryptedText = new String(decryptedData);
System.out.println("Decrypted: " + decryptedText);
}
}
(5) 注意事項(xiàng)
- 密鑰長(zhǎng)度:推薦使用2048位或更長(zhǎng)的密鑰以確保安全性。
- 密鑰管理:公鑰可以公開(kāi),但私鑰必須保密,防止泄露。
- 性能:RSA加密和解密的速度相對(duì)較慢,不適合加密大量數(shù)據(jù)。
總結(jié)
綜上,實(shí)際使用中,常常根據(jù)自身系統(tǒng)特征選擇。比如:執(zhí)行效率、數(shù)據(jù)量、安全合規(guī)要求等,這里給出上述簡(jiǎn)易版整理。
加密算法 | 名稱(chēng) | 有效長(zhǎng)度 | 特性 | 是否加密解密 | 優(yōu)點(diǎn) | 缺點(diǎn) |
MD5 | MD5 散列算法 | 128位 | 散列函數(shù) | 不可逆 | 速度快,簡(jiǎn)單 | 安全性低,易受碰撞攻擊 |
AES | AES 加密算法 | 128/192/256位 | 對(duì)稱(chēng)加密 | 是 | 安全性高,效率高 | 無(wú)嚴(yán)重弱點(diǎn) |
DES | DES 加密算法 | 56位 | 對(duì)稱(chēng)加密 | 是 | 速度快,曾廣泛使用 | 密鑰短,安全性低 |
國(guó)密SM4 | SM4 加密算法 | 128位 | 對(duì)稱(chēng)加密 | 是 | 符合國(guó)內(nèi)標(biāo)準(zhǔn),安全性好 | 使用不如AES廣泛 |
RSA | RSA 加密算法 | 1024/2048位 | 非對(duì)稱(chēng)加密 | 是 | 非對(duì)稱(chēng)加密,適合數(shù)字簽名 | 計(jì)算量大,速度慢 |