網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
對(duì)稱(chēng)式加密
對(duì)稱(chēng)加密算法就是傳統(tǒng)的用一個(gè)密碼進(jìn)行加密和解密。例如,我們常用的WinZIP和WinRAR對(duì)壓縮包的加密和解密,就是使用對(duì)稱(chēng)加密算法
常見(jiàn)的對(duì)稱(chēng)加密算法有:
算法 | 密鑰長(zhǎng)度 | 工作模式 | 填充模式 |
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/... |
密鑰長(zhǎng)度直接決定加密強(qiáng)度,工作模式和填充模式可以看成是對(duì)稱(chēng)加密算法的參數(shù)和格式選擇。
DES算法由于密鑰過(guò)短,可以在短時(shí)間內(nèi)被暴力破解,所以現(xiàn)在已經(jīng)不安全了。
AES是目前應(yīng)用最廣泛的加密算法,比較常見(jiàn)的工作模式是ECB和CBC。
ECB模式加密與解密
ECB模式只需要一個(gè)固定長(zhǎng)度的密鑰,固定的明文會(huì)生成固定的密文。
ECB模式加/解密的代碼編寫(xiě)需要根據(jù)算法名稱(chēng)/工作模式/填充模式獲取Cipher實(shí)例,再通過(guò)算法名稱(chēng)和固定的密鑰獲取SecretKey實(shí)例,之后通過(guò)SecretKey實(shí)例和設(shè)置的加/解密模式初始化秘鑰,最后就可以根據(jù)傳入的明文/密文,進(jìn)行加密/解密。
具體代碼如下:
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對(duì)稱(chēng)加密
//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 {
//創(chuàng)建密碼對(duì)象,需要傳入算法/工作模式/填充模式
Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
//根據(jù)key的字節(jié)內(nèi)容,“恢復(fù)”秘鑰對(duì)象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//初始化秘鑰:設(shè)置加密模式ENCRYPT_MOED
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
//根據(jù)原始內(nèi)容(字節(jié)),進(jìn)行加密
return cipher.doFinal(input);
}
//解密:
public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
//創(chuàng)建密碼對(duì)象,需要傳入算法/工作模式/填充模式
Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
//根據(jù)key的字節(jié)內(nèi)容,“恢復(fù)”秘鑰對(duì)象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//初始化秘鑰:設(shè)置解密模式ENCRYPT_MOED
cipher.init(Cipher.DECRYPT_MODE, keySpec);
//根據(jù)原始內(nèi)容(字節(jié)),進(jìn)行解密
return cipher.doFinal(input);
}
}
運(yùn)行結(jié)果如下:
?
CBC模式加密與解密
CBC模式下,需要一個(gè)隨機(jī)生成的16字節(jié)IV參數(shù),使用SecureRandom生成。
因?yàn)槎嗔艘粋€(gè)IvParameterSpec實(shí)例,因此,初始化方法需要調(diào)用Cipher的重載方法傳入IV參數(shù)和操作模式、秘鑰。
具體代碼如下:
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對(duì)稱(chēng)加密
//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(加密內(nèi)容):"+Base64.getEncoder().encodeToString(encrypted));
//解密:
byte[] decrypted=decrypt(key,encrypted);
System.out.println("Decrypted(解密內(nèi)容:"+new String(decrypted));
}
//加密:
public static byte[] encrypt(byte[] key,byte[] input) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
//設(shè)置算法名稱(chēng)/工作模式CBC/填充模式
Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
//“恢復(fù)”秘鑰對(duì)象
SecretKey keySpec=new SecretKeySpec(key, "AES");
//CBC模式需要生成一個(gè)16bytes的initialization vector:
SecureRandom sr=SecureRandom.getInstanceStrong();
byte[] iv=sr.generateSeed(16); //生成16個(gè)字節(jié)的隨機(jī)數(shù)
System.out.println(Arrays.toString(iv));
IvParameterSpec ivps=new IvParameterSpec(iv); //隨機(jī)數(shù)封裝成IvParameterSpec參數(shù)對(duì)象
//初始化秘鑰:操作模式、秘鑰、IV參數(shù)
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"); //密碼對(duì)象
SecretKey keySpec=new SecretKeySpec(key, "AES"); //恢復(fù)秘鑰
IvParameterSpec ivps=new IvParameterSpec(iv); //恢復(fù)IV
//初始化秘鑰:操作模式、秘鑰、IV參數(shù)
cipher.init(Cipher.DECRYPT_MODE, keySpec,ivps);
//解密操作
return cipher.doFinal(data);
}
}
運(yùn)行結(jié)果如下:
?
?觀(guān)察輸出,可以發(fā)現(xiàn)每次生成的IV不同,密文也不同。
另外,DH算法是一種密鑰交換協(xié)議,通信雙方通過(guò)不安全的信道最終協(xié)商出一個(gè)共同的密鑰(這個(gè)密鑰不會(huì)通過(guò)網(wǎng)絡(luò)傳輸),然后進(jìn)行對(duì)稱(chēng)加密傳輸。
非對(duì)稱(chēng)式加密算法
非對(duì)稱(chēng)加密:加密和解密使用的不是相同的密鑰,只有同一個(gè)公鑰-私鑰對(duì)才能正常加解密。
非對(duì)稱(chēng)加密的典型算法就是RSA算法,它的密鑰有256/512/1024/2048/4096等不同的長(zhǎng)度。長(zhǎng)度越長(zhǎng),密碼強(qiáng)度越大,當(dāng)然計(jì)算速度也越慢。
非對(duì)稱(chēng)加密的優(yōu)點(diǎn):對(duì)稱(chēng)加密需要協(xié)商密鑰,而非對(duì)稱(chēng)加密可以安全地公開(kāi)各自的公鑰,在N個(gè)人之間通信的時(shí)候:使用非對(duì)稱(chēng)加密只需要N個(gè)密鑰對(duì),每個(gè)人只管理自己的密鑰對(duì)。而使用對(duì)稱(chēng)加密需要?jiǎng)t需要N*(N-1)/2個(gè)密鑰,因此每個(gè)人需要管理N-1個(gè)密鑰,密鑰管理難度大,而且非常容易泄漏。
非對(duì)稱(chēng)加密的缺點(diǎn):運(yùn)算速度非常慢,比對(duì)稱(chēng)加密要慢很多。
所以,在實(shí)際應(yīng)用的時(shí)候,非對(duì)稱(chēng)加密總是和對(duì)稱(chēng)加密一起使用。
原文鏈接:https://blog.csdn.net/qq_50587186/article/details/125918772
相關(guān)推薦
- 2022-04-09 一起來(lái)學(xué)習(xí)一下python的數(shù)據(jù)類(lèi)型_python
- 2023-07-16 spring boot 實(shí)現(xiàn)token攔截
- 2024-02-26 openJDK awt 字體支持
- 2023-10-09 mobx中react的觀(guān)察者
- 2024-01-31 1273 - Unknown collation: ‘utf8mb4_0900_ai_ci‘, Ti
- 2022-08-29 .NET?Core自定義配置文件_實(shí)用技巧
- 2022-11-02 Python中turtle庫(kù)常用代碼匯總_python
- 2022-09-18 C++?STL反向迭代器的實(shí)現(xiàn)_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支