Java中的對(duì)稱加密詳解
采用單鑰密碼系統(tǒng)的加密方法,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密,這種加密方法稱為對(duì)稱加密,也稱為單密鑰加密。
常見的對(duì)稱加密方法
DES : Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法,1977年被美國(guó)聯(lián)邦政府的國(guó)家標(biāo)準(zhǔn)局確定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS),并授權(quán)在非密級(jí)政府通信中使用,隨后該算法在國(guó)際上廣泛流傳開來(lái)。
AES : Advanced Encryption Standard, 高級(jí)加密標(biāo)準(zhǔn) .在密碼學(xué)中又稱Rijndael加密法,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用。
代碼案例
byte[] 和16進(jìn)制字符串相互轉(zhuǎn)換
private byte[] hexStringToBytes(String hexString) {
if (hexString.length() % 2 != 0) throw new IllegalArgumentException("hexString length not valid");
int length = hexString.length() / 2;
byte[] resultBytes = new byte[length];
for (int index = 0; index < length; index++) {
String result = hexString.substring(index * 2, index * 2 + 2);
resultBytes[index] = Integer.valueOf(Integer.parseInt(result, 16)).byteValue();
}
return resultBytes;
}
private String bytesToHexString(byte[] sources) {
if (sources == null) return null;
StringBuilder stringBuffer = new StringBuilder();
for (byte source : sources) {
String result = Integer.toHexString(source& 0xff);
if (result.length() < 2) {
result = "0" + result;
}
stringBuffer.append(result);
}
return stringBuffer.toString();
}
DES 加密和解密
private String encryptByDES(String input,String key) throws Exception {
// 算法
String algorithm = "DES";
String transformation = "DES";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是8位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 進(jìn)行加密
byte[] bytes = cipher.doFinal(input.getBytes());
return bytesToHexString(bytes);
}
private String decryptByDES(String input,String key)throws Exception{
// 算法
String algorithm = "DES";
String transformation = "DES";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是8位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks);
// 進(jìn)行解密
byte [] inputBytes = hexStringToBytes(input);
byte[] bytes = cipher.doFinal(inputBytes);
return new String(bytes);
}
AES 加密和解密
private String encryptByAES(String input,String key) throws Exception {
// 算法
String algorithm = "AES";
String transformation = "AES";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是16位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 進(jìn)行加密
byte[] bytes = cipher.doFinal(input.getBytes());
return bytesToHexString(bytes);
}
private String decryptByAES(String input,String key)throws Exception{
// 算法
String algorithm = "AES";
String transformation = "AES";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是16位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks);
// 進(jìn)行解密
byte [] inputBytes = hexStringToBytes(input);
byte[] bytes = cipher.doFinal(inputBytes);
return new String(bytes);
}
加密模式
ECB
Electronic codebook, 電子密碼本. 需要加密的消息按照塊密碼的塊大小被分為數(shù)個(gè)塊,并對(duì)每個(gè)塊進(jìn)行獨(dú)立加密

優(yōu)點(diǎn):并行加密,速度快
缺點(diǎn):同樣的明文,加密成同樣的密文,容易被破解,不利于安全保護(hù)CBC

優(yōu)點(diǎn):同樣的原文生成不同的密文
缺點(diǎn):串行處理,速度慢
注意: 需要一個(gè)初始的向量值IV
填充模式
當(dāng)需要按塊處理的數(shù)據(jù), 數(shù)據(jù)長(zhǎng)度不符合塊處理需求時(shí), 按照一定的方法填充滿塊長(zhǎng)的規(guī)則
NoPadding
不填充.
在DES加密算法下, 要求原文長(zhǎng)度必須是8byte的整數(shù)倍
在AES加密算法下, 要求原文長(zhǎng)度必須是16byte的整數(shù)倍PKCS5Padding
數(shù)據(jù)塊的大小為8位, 不夠就補(bǔ)足
注意
默認(rèn)情況下, 加密模式和填充模式為 : ECB/PKCS5Padding
如果使用CBC模式, 在初始化Cipher對(duì)象時(shí), 需要增加參數(shù), 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());
加密模式和填充模式
AES/CBC/NoPadding (128) AES/CBC/PKCS5Padding (128) AES/ECB/NoPadding (128) AES/ECB/PKCS5Padding (128) DES/CBC/NoPadding (56) DES/CBC/PKCS5Padding (56) DES/ECB/NoPadding (56) DES/ECB/PKCS5Padding (56) DESede/CBC/NoPadding (168) DESede/CBC/PKCS5Padding (168) DESede/ECB/NoPadding (168) DESede/ECB/PKCS5Padding (168) RSA/ECB/PKCS1Padding (1024, 2048) RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048) RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
使用加密模式和填充模式的案例
private String encryptByAES(String input,String key) throws Exception {
// 算法
String algorithm = "AES";
String transformation = "AES/CBC/PKCS5Padding";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是16位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 初始向量值長(zhǎng)度必須是16位
String ivStr = "2222222222222221";
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks,iv);
// 進(jìn)行加密
byte[] bytes = cipher.doFinal(input.getBytes());
return bytesToHexString(bytes);
}
private String decryptByAES(String input,String key)throws Exception{
// 算法
String algorithm = "AES";
String transformation = "AES/CBC/PKCS5Padding";
// Cipher:密碼,獲取加密對(duì)象
// transformation:參數(shù)表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長(zhǎng)度必須是16位
// 第二個(gè)參數(shù)表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 初始向量值長(zhǎng)度必須是16位
String ivStr = "2222222222222221";
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
// 對(duì)加密進(jìn)行初始化
// 第一個(gè)參數(shù):表示模式,有加密模式和解密模式
// 第二個(gè)參數(shù):表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks,iv);
// 進(jìn)行解密
byte [] inputBytes = hexStringToBytes(input);
byte[] bytes = cipher.doFinal(inputBytes);
return new String(bytes);
}
總結(jié)
到此這篇關(guān)于Java中的對(duì)稱加密詳解的文章就介紹到這了,更多相關(guān)Java對(duì)稱加密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Dom4j解析xml復(fù)雜多節(jié)點(diǎn)報(bào)文方式
這篇文章主要介紹了Dom4j解析xml復(fù)雜多節(jié)點(diǎn)報(bào)文方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
spring?data?jpa如何使用自定義repository實(shí)現(xiàn)類
這篇文章主要介紹了spring?data?jpa如何使用自定義repository實(shí)現(xiàn)類,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
詳解IntelliJ IDEA中TortoiseSVN修改服務(wù)器地址的方法
這篇文章主要介紹了詳解IntelliJ IDEA中TortoiseSVN修改服務(wù)器地址的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Java動(dòng)態(tài)代理機(jī)制詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)代理機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
基于jmeter實(shí)現(xiàn)跨線程組傳遞token過(guò)程圖解
這篇文章主要介紹了基于jmeter實(shí)現(xiàn)跨線程組傳遞token,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Java class文件格式之特殊字符串_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
特殊字符串出現(xiàn)在class文件中的常量池中,本著循序漸進(jìn)和減少跨度的原則, 首先把class文件中的特殊字符串做一個(gè)詳細(xì)的介紹, 然后再回過(guò)頭來(lái)繼續(xù)講解常量池,對(duì)java class 文件格式相關(guān)知識(shí)感興趣的的朋友一起學(xué)習(xí)吧2017-06-06
基于jenkins實(shí)現(xiàn)發(fā)布node.js項(xiàng)目
這篇文章主要介紹了基于jenkins實(shí)現(xiàn)發(fā)布node.js項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

