Java中的對稱加密詳解
采用單鑰密碼系統的加密方法,同一個密鑰可以同時用作信息的加密和解密,這種加密方法稱為對稱加密,也稱為單密鑰加密。
常見的對稱加密方法
DES : Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的塊算法,1977年被美國聯邦政府的國家標準局確定為聯邦資料處理標準(FIPS),并授權在非密級政府通信中使用,隨后該算法在國際上廣泛流傳開來。
AES : Advanced Encryption Standard, 高級加密標準 .在密碼學中又稱Rijndael加密法,是美國聯邦政府采用的一種區(qū)塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。
代碼案例
byte[] 和16進制字符串相互轉換
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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是8位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 進行加密
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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是8位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks);
// 進行解密
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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是16位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 進行加密
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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是16位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks);
// 進行解密
byte [] inputBytes = hexStringToBytes(input);
byte[] bytes = cipher.doFinal(inputBytes);
return new String(bytes);
}
加密模式
ECB
Electronic codebook, 電子密碼本. 需要加密的消息按照塊密碼的塊大小被分為數個塊,并對每個塊進行獨立加密

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

優(yōu)點:同樣的原文生成不同的密文
缺點:串行處理,速度慢
注意: 需要一個初始的向量值IV
填充模式
當需要按塊處理的數據, 數據長度不符合塊處理需求時, 按照一定的方法填充滿塊長的規(guī)則
NoPadding
不填充.
在DES加密算法下, 要求原文長度必須是8byte的整數倍
在AES加密算法下, 要求原文長度必須是16byte的整數倍PKCS5Padding
數據塊的大小為8位, 不夠就補足
注意
默認情況下, 加密模式和填充模式為 : ECB/PKCS5Padding
如果使用CBC模式, 在初始化Cipher對象時, 需要增加參數, 初始化向量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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是16位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 初始向量值長度必須是16位
String ivStr = "2222222222222221";
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.ENCRYPT_MODE,sks,iv);
// 進行加密
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:密碼,獲取加密對象
// transformation:參數表示使用什么類型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘鑰規(guī)則
// 第一個參數表示:密鑰,key的字節(jié)數組 長度必須是16位
// 第二個參數表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 初始向量值長度必須是16位
String ivStr = "2222222222222221";
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
// 對加密進行初始化
// 第一個參數:表示模式,有加密模式和解密模式
// 第二個參數:表示秘鑰規(guī)則
cipher.init(Cipher.DECRYPT_MODE,sks,iv);
// 進行解密
byte [] inputBytes = hexStringToBytes(input);
byte[] bytes = cipher.doFinal(inputBytes);
return new String(bytes);
}
總結
到此這篇關于Java中的對稱加密詳解的文章就介紹到這了,更多相關Java對稱加密內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring?data?jpa如何使用自定義repository實現類
這篇文章主要介紹了spring?data?jpa如何使用自定義repository實現類,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
詳解IntelliJ IDEA中TortoiseSVN修改服務器地址的方法
這篇文章主要介紹了詳解IntelliJ IDEA中TortoiseSVN修改服務器地址的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
Java動態(tài)代理機制詳解_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了Java動態(tài)代理機制,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
Java class文件格式之特殊字符串_動力節(jié)點Java學院整理
特殊字符串出現在class文件中的常量池中,本著循序漸進和減少跨度的原則, 首先把class文件中的特殊字符串做一個詳細的介紹, 然后再回過頭來繼續(xù)講解常量池,對java class 文件格式相關知識感興趣的的朋友一起學習吧2017-06-06

