網站首頁 編程語言 正文
? ? 對稱加密算法就是傳統的用一個密碼進行加密和解密。例如:我們常用的WinZip和WinRAR對壓縮包的加密和解密就是使用的對稱加密算法。
? ? ? ? 常見的對稱加密算法有:
目前主流的對稱式加密算法為AES加密算法
我們以AES算法,ECB工作模式為例,看看如如計算哈希:
一:加密:
1、創建加密對象Cipher
2、根據key內容,恢復密鑰對象
3、初始化密鑰,設置加密模式
4、根據原始內容進行加密
5、輸出加密結果
二:解密
1、創建解密對象Cipher
2、根據key內容,恢復密鑰對象
3、初始化密鑰,設置解密模式
4、根據原始內容進行解密
5、輸出解密結果
public class Demo07 {
public static void main(String[] args) {
// 對稱加密算法
// AES算法 ECB模式
try {
// 密文
byte[] messageByte = "12346".getBytes();
// 密鑰
byte[] keyByte = "1234567891234567".getBytes();
// 加密
// 創建密碼對象
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// 根據key內容,恢復密鑰對象
SecretKey keySpec = new SecretKeySpec(keyByte, "AES");
// 初始化密鑰,設置加密模式
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// 根據原始內容,進行加密
byte[] resByteArray = cipher.doFinal(messageByte);
// 輸出加密內容
System.out.println(Base64.getEncoder().encodeToString(resByteArray));
// 解密
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] aaaByteArray = cipher.doFinal(resByteArray);
// 輸出加密內容
System.out.println(new String(aaaByteArray));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
加解密結果:
?根據結果可以發現,加解密步驟大致相同,但是要保證雙方密鑰在交換的過程中保證安全性,一般我們會采用DH算法,也就是密鑰交換算法,使用了這種算法可以保證雙方的共享密鑰一致,并且保證了密鑰的安全性。一般情況下,對稱式加密算法都是與密鑰交換算法配合起來使用的。
再來看非對稱式加密算法:
非對稱加密算法使用的是一對密鑰,使用公鑰加密私鑰解密的方法,這就使得在通信初期,要想雙方可以通信,必須讓A方先發送公鑰給B方,B方通過接受的公鑰進行加密,再將密文發送給A方,A方再使用私鑰進行解密。盡管這樣會使效率降低,但能大幅度保證安全傳輸。一般情況下,都是對稱式加密算法與非對稱式加密算法配合起來使用。
非對稱式加密算法如下:
public class Main04 {
public static void main(String[] args) {
// Bob和Alice:
Person bob = new Person("Bob");
Person alice = new Person("Alice");
// 各自生成KeyPair: 公鑰+私鑰
bob.generateKeyPair();
alice.generateKeyPair();
// 雙方交換各自的PublicKey(公鑰):
// Bob根據Alice的PublicKey生成自己的本地密鑰(共享公鑰):
bob.generateSecretKey(alice.publicKey.getEncoded());
// Alice根據Bob的PublicKey生成自己的本地密鑰(共享公鑰):
alice.generateSecretKey(bob.publicKey.getEncoded());
// 檢查雙方的本地密鑰是否相同:
bob.printKeys();
alice.printKeys();
// 雙方的SecretKey相同,后續通信將使用SecretKey作為密鑰進行AES加解密...
}
}
// 用戶類
class Person {
public final String name; // 姓名
// 密鑰
public PublicKey publicKey; // 公鑰
private PrivateKey privateKey; // 私鑰
private byte[] secretKey; // 本地秘鑰(共享密鑰)
// 構造方法
public Person(String name) {
this.name = name;
}
// 生成本地KeyPair:(公鑰+私鑰)
public void generateKeyPair() {
try {
// 創建DH算法的“秘鑰對”生成器
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");
kpGen.initialize(512);
// 生成一個"密鑰對"
KeyPair kp = kpGen.generateKeyPair();
this.privateKey = kp.getPrivate(); // 私鑰
this.publicKey = kp.getPublic(); // 公鑰
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
// 按照 "對方的公鑰" => 生成"共享密鑰"
public void generateSecretKey(byte[] receivedPubKeyBytes) {
try {
// 從byte[]恢復PublicKey:
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(receivedPubKeyBytes);
// 根據DH算法獲取KeyFactory
KeyFactory kf = KeyFactory.getInstance("DH");
// 通過KeyFactory創建公鑰
PublicKey receivedPublicKey = kf.generatePublic(keySpec);
// 生成本地密鑰(共享公鑰)
KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
keyAgreement.init(this.privateKey); // 初始化"自己的PrivateKey"
keyAgreement.doPhase(receivedPublicKey, true); // 根據"對方的PublicKey"
// 生成SecretKey本地密鑰(共享公鑰)
this.secretKey = keyAgreement.generateSecret();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public void printKeys() {
System.out.printf("Name: %s\n", this.name);
System.out.printf("Private key: %x\n", new BigInteger(1, this.privateKey.getEncoded()));
System.out.printf("Public key: %x\n", new BigInteger(1, this.publicKey.getEncoded()));
System.out.printf("Secret key: %x\n", new BigInteger(1, this.secretKey));
}
}
結果如下:
?總的來說:對稱式加密使用同一個密鑰進行加密和解密。而非對稱式加密就是加密和解密使用的是不同的密鑰,只有同一對的公鑰和私鑰才能正常進行加密和解密。
原文鏈接:https://blog.csdn.net/qq_17845335/article/details/125918566
相關推薦
- 2022-03-17 正確使用dotnet-*工具的方法_實用技巧
- 2022-11-19 Python變量和數據類型和數據類型的轉換_python
- 2022-01-29 調用存儲命令:將sqlserver表中的數據導出sql語句或生成insert into語句
- 2022-06-19 mybatis-plus的sql語句打印問題小結_MsSql
- 2022-07-22 ubuntu操作系統安裝docker部署sqllabs靶機
- 2022-01-06 springmvc中的model和HttpServletRequest的區別詳細分析
- 2022-11-17 React通過classnames庫添加類的方法_React
- 2022-07-11 Verilog中$display和$write任務以及格式化輸出
- 最近更新
-
- 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同步修改后的遠程分支