Java中的對稱加密詳解
采用單鑰密碼系統(tǒng)的加密方法,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密,這種加密方法稱為對稱加密,也稱為單密鑰加密。
常見的對稱加密方法
DES : Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法,1977年被美國聯(lián)邦政府的國家標(biāo)準(zhǔn)局確定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS),并授權(quán)在非密級(jí)政府通信中使用,隨后該算法在國際上廣泛流傳開來。
AES : Advanced Encryption Standard, 高級(jí)加密標(biāo)準(zhǔn) .在密碼學(xué)中又稱Rijndael加密法,是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來替代原先的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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是8位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 對加密進(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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是8位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 對加密進(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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是16位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 對加密進(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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是16位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 對加密進(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è)塊,并對每個(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ù)長度不符合塊處理需求時(shí), 按照一定的方法填充滿塊長的規(guī)則
NoPadding
不填充.
在DES加密算法下, 要求原文長度必須是8byte的整數(shù)倍
在AES加密算法下, 要求原文長度必須是16byte的整數(shù)倍PKCS5Padding
數(shù)據(jù)塊的大小為8位, 不夠就補(bǔ)足
注意
默認(rèn)情況下, 加密模式和填充模式為 : ECB/PKCS5Padding
如果使用CBC模式, 在初始化Cipher對象時(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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是16位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 初始向量值長度必須是16位 String ivStr = "2222222222222221"; IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes()); // 對加密進(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:密碼,獲取加密對象 // transformation:參數(shù)表示使用什么類型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘鑰規(guī)則 // 第一個(gè)參數(shù)表示:密鑰,key的字節(jié)數(shù)組 長度必須是16位 // 第二個(gè)參數(shù)表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 初始向量值長度必須是16位 String ivStr = "2222222222222221"; IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes()); // 對加密進(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中的對稱加密詳解的文章就介紹到這了,更多相關(guān)Java對稱加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java定時(shí)任務(wù)實(shí)現(xiàn)的4種方式小結(jié)
這篇文章主要介紹了java定時(shí)任務(wù)實(shí)現(xiàn)的4種方式小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Java的Netty進(jìn)階之Future和Promise詳解
這篇文章主要介紹了Java的Netty進(jìn)階之Future和Promise詳解,Netty 是基于 Java NIO 的異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,使用 Netty 可以快速開發(fā)網(wǎng)絡(luò)應(yīng)用,Netty 提供了高層次的抽象來簡化 TCP 和 UDP 服務(wù)器的編程,但是你仍然可以使用底層的 API,需要的朋友可以參考下2023-11-11Mapper層繼承BaseMapper<T>需要引入的pom依賴方式
這篇文章主要介紹了Mapper層繼承BaseMapper<T>需要引入的pom依賴方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01IDEA 啟動(dòng) Tomcat 項(xiàng)目輸出亂碼的解決方法
這篇文章主要介紹了IDEA 啟動(dòng) Tomcat 項(xiàng)目輸出亂碼的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程
這篇文章主要介紹了springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Java設(shè)計(jì)模式常用的七大原則總結(jié)
今天給大家總結(jié)了Java設(shè)計(jì)模式的七大原則,主要有單一職責(zé)原則,接口隔離原則,依賴倒轉(zhuǎn)原則,里氏替換原則等,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06java線程并發(fā)blockingqueue類使用示例
BlockingQueue是一種特殊的Queue,若BlockingQueue是空的,從BlockingQueue取東西的操作將會(huì)被阻斷進(jìn)入等待狀態(tài)直到BlocingkQueue進(jìn)了新貨才會(huì)被喚醒,下面是用BlockingQueue來實(shí)現(xiàn)Producer和Consumer的例子2014-01-01