網站首頁 編程語言 正文
對稱式加密
對稱加密算法就是傳統的用一個密碼進行加密和解密。例如,我們常用的WinZIP和WinRAR對壓縮包的加密和解密,就是使用對稱加密算法
常見的對稱加密算法有:
算法 | 密鑰長度 | 工作模式 | 填充模式 |
DES | 56/64 | ECB/CBC/PCBC/CTR/... | NoPadding/PKCS5Padding/... |
AES | 128/192/256 | ECB/CBC/PCBC/CTR/... | NoPadding/PKCS5Padding/PKCS7Padding/... |
IDEA | 128 | ECB | PKCS5Padding/PKCS7Padding/... |
密鑰長度直接決定加密強度,工作模式和填充模式可以看成是對稱加密算法的參數和格式選擇。
DES算法由于密鑰過短,可以在短時間內被暴力破解,所以現在已經不安全了。
AES是目前應用最廣泛的加密算法,比較常見的工作模式是ECB和CBC。
ECB模式加密與解密
ECB模式只需要一個固定長度的密鑰,固定的明文會生成固定的密文。
ECB模式加/解密的代碼編寫需要根據算法名稱/工作模式/填充模式獲取Cipher實例,再通過算法名稱和固定的密鑰獲取SecretKey實例,之后通過SecretKey實例和設置的加/解密模式初始化秘鑰,最后就可以根據傳入的明文/密文,進行加密/解密。
具體代碼如下:
package com.gjh.demo;
import java.io.ObjectInputStream.GetField;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class Text02 {
//AES對稱加密
//ECB工作模式
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
//原文
String message="Hello,world!";
System.out.println("Message:"+message);
//128位秘鑰=16 bytes key:
byte[] key="1234567890abcdef1234567890abcdef".getBytes();
//加密:
byte[] data=message.getBytes();
byte[] encrypted=encrypt(key,data);
System.out.println("Encrypted(加密):"+Base64.getEncoder().encode(encrypted));
//解密:
byte[] decrypted=decrypt(key,encrypted);
System.out.println("Decrypted:"+new String(decrypted));
}
//加密:
public static byte[] encrypt(byte[] key,byte[] input) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
//創建密碼對象,需要傳入算法/工作模式/填充模式
Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
//根據key的字節內容,“恢復”秘鑰對象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//初始化秘鑰:設置加密模式ENCRYPT_MOED
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
//根據原始內容(字節),進行加密
return cipher.doFinal(input);
}
//解密:
public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
//創建密碼對象,需要傳入算法/工作模式/填充模式
Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
//根據key的字節內容,“恢復”秘鑰對象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//初始化秘鑰:設置解密模式ENCRYPT_MOED
cipher.init(Cipher.DECRYPT_MODE, keySpec);
//根據原始內容(字節),進行解密
return cipher.doFinal(input);
}
}
運行結果如下:
?
CBC模式加密與解密
CBC模式下,需要一個隨機生成的16字節IV參數,使用SecureRandom生成。
因為多了一個IvParameterSpec實例,因此,初始化方法需要調用Cipher的重載方法傳入IV參數和操作模式、秘鑰。
具體代碼如下:
package com.gjh.demo;
import java.io.ObjectInputStream.GetField;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Text03 {
//AES對稱加密
//CBC工作模式
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
//原文
String message="Hello,world!";
System.out.println("Message(原始信息):"+message);
//256位秘鑰=32 bytes key:
byte[] key="1234567890abcdef1234567890abcdef".getBytes();
//加密:
byte[] data=message.getBytes();
byte[] encrypted=encrypt(key,data);
System.out.println("Encrypted(加密內容):"+Base64.getEncoder().encodeToString(encrypted));
//解密:
byte[] decrypted=decrypt(key,encrypted);
System.out.println("Decrypted(解密內容:"+new String(decrypted));
}
//加密:
public static byte[] encrypt(byte[] key,byte[] input) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
//設置算法名稱/工作模式CBC/填充模式
Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
//“恢復”秘鑰對象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//CBC模式需要生成一個16bytes的initialization vector:
SecureRandom sr=SecureRandom.getInstanceStrong();
byte[] iv=sr.generateSeed(16); //生成16個字節的隨機數
System.out.println(Arrays.toString(iv));
IvParameterSpec ivps=new IvParameterSpec(iv); //隨機數封裝成IvParameterSpec參數對象
//初始化秘鑰:操作模式、秘鑰、IV參數
cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivps);
//加密
byte[] data=cipher.doFinal(input);
//IV不需要保密,把IV和密文一起返回
return join(iv,data);
}
private static byte[] join(byte[] bs1, byte[] bs2) {
byte[] r=new byte[bs1.length+bs2.length];
System.arraycopy(bs1,0,r,0,bs1.length);
System.arraycopy(bs2,0,r,bs1.length,bs2.length);
return r;
}
//解密:
public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
//把input分割成IV和密文
byte[] iv=new byte[16];
byte[] data=new byte[input.length-16];
System.arraycopy(input,0,iv,0,16);
System.arraycopy(input, 16, data, 0, data.length);
System.out.println(Arrays.toString(iv));
//解密:
Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding"); //密碼對象
SecretKey keySpec=new SecretKeySpec(key, "AES"); //恢復秘鑰
IvParameterSpec ivps=new IvParameterSpec(iv); //恢復IV
//初始化秘鑰:操作模式、秘鑰、IV參數
cipher.init(Cipher.DECRYPT_MODE, keySpec,ivps);
//解密操作
return cipher.doFinal(data);
}
}
運行結果如下:
?
?觀察輸出,可以發現每次生成的IV不同,密文也不同。
另外,DH算法是一種密鑰交換協議,通信雙方通過不安全的信道最終協商出一個共同的密鑰(這個密鑰不會通過網絡傳輸),然后進行對稱加密傳輸。
非對稱式加密算法
非對稱加密:加密和解密使用的不是相同的密鑰,只有同一個公鑰-私鑰對才能正常加解密。
非對稱加密的典型算法就是RSA算法,它的密鑰有256/512/1024/2048/4096等不同的長度。長度越長,密碼強度越大,當然計算速度也越慢。
非對稱加密的優點:對稱加密需要協商密鑰,而非對稱加密可以安全地公開各自的公鑰,在N個人之間通信的時候:使用非對稱加密只需要N個密鑰對,每個人只管理自己的密鑰對。而使用對稱加密需要則需要N*(N-1)/2個密鑰,因此每個人需要管理N-1個密鑰,密鑰管理難度大,而且非常容易泄漏。
非對稱加密的缺點:運算速度非常慢,比對稱加密要慢很多。
所以,在實際應用的時候,非對稱加密總是和對稱加密一起使用。
原文鏈接:https://blog.csdn.net/qq_50587186/article/details/125918772
相關推薦
- 2023-07-22 SpringBoot中@Cacheable如何使用
- 2022-12-15 Redis分布式鎖如何設置超時時間_Redis
- 2022-11-03 APAP?ALV進階寫法及優化詳解_其它綜合
- 2022-04-18 python中出現invalid?syntax報錯的幾種原因分析_python
- 2023-04-26 C語言實現數組元素排序方法詳解_C 語言
- 2022-10-17 Python如何提取csv數據并篩選指定條件數據詳解_python
- 2022-09-15 docker倉庫登錄及配置insecure-registries的方法_docker
- 2022-08-28 go?zero微服務高在請求量下如何優化_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支