【本文版權歸微信公衆號"代碼藝術"(ID:onblog)全部,如果轉載請務必保留本段原創聲明,違者必究。如果文章有不足之處,歡迎關注微信公衆號私信與我進行交流!】java
對稱加密算法是應用較早的加密算法,技術成熟。在對稱加密算法中,數據發信方將明文和加密密鑰一塊兒通過特殊加密算法處理後,使其變成複雜的加密密文發送出去。收信方收到密文後,若想解讀原文,則須要使用加密用過的密鑰及相同算法的逆算法對密文進行解密,才能使其恢復成可讀明文。算法
在對稱加密算法中,使用的密鑰只有一個,發收信雙方都使用這個密鑰對數據進行加密和解密,這就要求解密方事先必須知道加密密鑰。apache
對稱加密算法的特色是算法公開、計算量小、加密速度快、加密效率高。安全
不足之處是,交易雙方都使用一樣鑰匙,安全性得不到保證。微信
在計算機系統中普遍使用的對稱加密算法有DES和IDEA等。由於DES近年來屢屢被破解,因此,美國國家標準局倡導的AES即將做爲新標準取代DES。dom
DES算法爲密碼體制中的對稱密碼體制,又被稱爲美國數據加密標準,是1972年美國IBM公司研製的對稱密碼體制加密算法。ide
明文按64位進行分組,密鑰長64位,密鑰事實上是56位參與DES運算(第八、1六、2四、3二、40、4八、5六、64位是校驗位, 使得每一個密鑰都有奇數個1)分組後的明文組和56位的密鑰按位替代或交換的方法造成密文組的加密方法。函數
密鑰長度 | 默認 | 工做模式 | 填充方式 | 實現方 |
---|---|---|---|---|
56 | 56 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到12八、OFB、OFB8到128 | NoPadding、PKCS5Padding、ISO10126Padding | JDK |
64 | 56 | 同上 | PKCS7Padding、ISO10126d2Padding、X932Padding、ISO7816d4Padding、ZeroBytePadding | BC |
引入Bouncy Castle依賴:加密
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15</artifactId> <version>1.46</version> </dependency>
引入Commons Codec依賴:設計
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
Java代碼實現:
import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class DES { public static final String src = "des test"; public static void main(String[] args) { jdkDES(); bcDES(); } // 用jdk實現: public static void jdkDES() { try { // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] bytesKey = secretKey.getEncoded(); // KEY轉換 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); Key convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk des encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("jdk des decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } // 用bouncy castle實現: public static void bcDES() { try { Security.addProvider(new BouncyCastleProvider()); // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DES", "BC"); keyGenerator.getProvider(); keyGenerator.init(56); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] bytesKey = secretKey.getEncoded(); // KEY轉換 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); Key convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("bc des encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("bc des decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } }
應用例子:
密碼學中,三重數據加密算法(英語:Triple Data Encryption Algorithm,縮寫爲TDEA,Triple DEA),或稱3DES(Triple DES),是一種對稱密鑰加密塊密碼,至關因而對每一個數據塊應用三次數據加密標準(DES)算法。因爲計算機運算能力的加強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES便是設計用來提供一種相對簡單的方法,即經過增長DES的密鑰長度來避免相似的***,而不是設計一種全新的塊密碼算法。
Java代碼實現:
import java.security.Key; import java.security.SecureRandom; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class DES3 { public static final String src = "3des test"; public static void main(String[] args) { jdk3DES(); bc3DES(); } // 用jdk實現: public static void jdk3DES() { try { // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); // 必須長度是:112或168 // keyGenerator.init(168); keyGenerator.init(new SecureRandom()); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] bytesKey = secretKey.getEncoded(); // KEY轉換 DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede"); Key convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk 3des encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("jdk 3des decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } // 用bouncy castle實現: public static void bc3DES() { try { Security.addProvider(new BouncyCastleProvider()); // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "BC"); keyGenerator.getProvider(); keyGenerator.init(168); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] bytesKey = secretKey.getEncoded(); // KEY轉換 DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede"); Key convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("bc 3des encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("bc 3des decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } }
【本文版權歸微信公衆號"代碼藝術"(ID:onblog)全部,如果轉載請務必保留本段原創聲明,違者必究。如果文章有不足之處,歡迎關注微信公衆號私信與我進行交流!】
高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。通過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPS PUB 197,並在2002年5月26日成爲有效的標準。2006年,高級加密標準已然成爲對稱密鑰加密中最流行的算法之一。
該算法爲比利時密碼學家Joan Daemen和Vincent Rijmen所設計,結合兩位做者的名字,以Rijndael爲名投稿高級加密標準的甄選流程。(Rijndael的發音近於"Rhine doll")
密鑰長度 | 默認 | 工做模式 | 填充方式 | 實現方 |
---|---|---|---|---|
12八、19二、256 | 128 | ECB、CBC、PCBC、CTR、CTS、CFB、CFB8到12八、OFB、OFB8到128 | NoPadding、PKCS5Padding、ISO10126Padding | JDK(256位密鑰須要得到無政策限制權限文件) |
同上 | 同上 | 同上 | PKCS7Padding、ZeroBytePadding | BC |
Java代碼實現:
import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class AES { public static final String src = "aes test"; public static void main(String[] args) { jdkAES(); bcAES(); } // 用jdk實現: public static void jdkAES() { try { // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] keyBytes = secretKey.getEncoded(); // KEY轉換 Key key = new SecretKeySpec(keyBytes, "AES"); // 加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk aes encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, key); result = cipher.doFinal(result); System.out.println("jdk aes decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } // 用bouncy castle實現: public static void bcAES() { try { Security.addProvider(new BouncyCastleProvider()); // 生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "BC"); keyGenerator.getProvider(); keyGenerator.init(128); // 產生密鑰 SecretKey secretKey = keyGenerator.generateKey(); // 獲取密鑰 byte[] keyBytes = secretKey.getEncoded(); // KEY轉換 Key key = new SecretKeySpec(keyBytes, "AES"); // 加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("bc aes encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, key); result = cipher.doFinal(result); System.out.println("bc aes decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } }
PBE算法(Password Based Encryption,基於口令加密)是一種基於口令的加密算法,其特色是使用口令代替了密鑰,而口令由用戶本身掌管,採用隨機數雜湊多重加密等方法保證數據的安全性。
PBE算法在加密過程當中並非直接使用口令來加密,而是加密的密鑰由口令生成,這個功能由PBE算法中的KDF函數完成。KDF函數的實現過程爲:將用戶輸入的口令首先經過「鹽」(salt)的擾亂產生準密鑰,再將準密鑰通過散列函數屢次迭代後生成最終加密密鑰,密鑰生成後,PBE算法再選用對稱加密算法對數據進行加密,能夠選擇DES、3DES、RC5等對稱加密算法。
具體實現以下:
算法 | 密鑰長度 | 默認 | 工做模式 | 填充方式 | 實現 |
---|---|---|---|---|---|
PBEWithMD5AndDES | 64 | 64 | CBC(下同) | PKCS5Padding、PKCS7Padding、ISO10126Padding、ZeroBytePadding、(下同) | BC(下同) |
PBEWithMD5AndRC2 | 112 | 128 | |||
PBEWithSHA1AndDES | 64 | 64 | |||
PBEWithSHA1AndRC2 | 128 | 128 | |||
PBEWithSHAAndIDEA-CBC | 128 | 128 | |||
PBEWithSHAAnd2-KeyTripleDES-CBC | 128 | 128 | |||
PBEWithSHAAnd3-KeyTripleDES-CBC | 192 | 192 | |||
PBEWithSHAAnd128BitRC2-CBC | 128 | 128 | |||
PBEWithSHAAnd40BitRC2-CBC | 40 | 40 | |||
PBEWithSHAAnd128BitRC4 | 128 | 128 | |||
PBEWithSHAAnd40BitRC4 | 40 | 40 | |||
PBEWithSHAAndTwofish-CBC | 256 | 256 |
Java代碼實現:
import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import org.apache.commons.codec.binary.Hex; public class PBE { public static final String src = "pbe test"; public static void main(String[] args) { jdkPBE(); } // 用jdk實現: public static void jdkPBE() { try { // 初始化鹽 SecureRandom random = new SecureRandom(); byte[] salt = random.generateSeed(8); // 口令與密鑰 String password = "timliu"; PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES"); Key key = factory.generateSecret(pbeKeySpec); // 加密 PBEParameterSpec pbeParameterSpac = new PBEParameterSpec(salt, 100); Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpac); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk pbe encrypt:" + Hex.encodeHexString(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpac); result = cipher.doFinal(result); System.out.println("jdk pbe decrypt:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } }
應用舉例:
【本文版權歸微信公衆號"代碼藝術"(ID:onblog)全部,如果轉載請務必保留本段原創聲明,違者必究。如果文章有不足之處,歡迎關注微信公衆號私信與我進行交流!】