本篇文來談談關於常見的一些加密算法,其實在此以前,對算法的瞭解並非太多。瞭解的層次只是基於加密算法的一些應用上。也來淺談一下加密算法在安全領域中的做用。寫本篇文也是基於算法的應用和實現,也是個人基本原則,能用就行。java
在加密算法裏面大體分爲四大類:對稱加密算法、非對稱加密算法、散列函數、組合加密。web
對稱加密:指的是加密的密鑰和解密的密鑰相同。算法
非對稱加密:指的是加密的密鑰和加密的密鑰不一樣。分爲公鑰和私鑰。shell
散列函數:主要用於驗證數據的完整性,長度不受限制,hash值容易計算,散列運算過程不可逆如:MD五、SHA數據庫
Hash,通常翻譯作散列、雜湊,或音譯爲哈希,是把任意長度的輸入(又叫作預映射pre-image)經過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,因此不可能從散列值來肯定惟一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。apache
md5的運用範圍也比較廣,好比在一些數據庫存儲密碼的時候會去使用到該算法去進行加密存儲。固然也能夠看到網上的一些md5破解的。可是他們都是基於彩虹表去跑,使用字典進行md5加密,而後把加密的值進行對比,從而判斷該md5值的明文。數組
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5demo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest md5 = MessageDigest.getInstance("MD5");//設置要返回的摘要算法對象 byte[] digest = md5.digest(name.getBytes()); //計算hash值 System.out.println(HexBin.encode(digest));//輸出hash結果 } }
安全散列算法(英語:Secure Hash Algorithm,縮寫爲SHA)是一個密碼散列函數家族,是FIPS所認證的安全散列算法。能計算出一個數字消息所對應到的,長度固定的字符串(又稱消息摘要)的算法。且若輸入的消息不一樣,它們對應到不一樣字符串的機率很高。安全
SHA家族的五個算法,分別是SHA-一、SHA-22四、SHA-25六、SHA-384,和SHA-512網絡
下面是一張對照圖。dom
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class jdksha1 { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest sha = MessageDigest.getInstance("SHA"); byte[] digest = sha.digest(name.getBytes()); System.out.println(HexBin.encode(digest)); } }
對稱加密算法,他的加解密密鑰都是同樣的。而對稱加密的算法又分兩大類,一種是每次對明文中的字節使用密鑰進行加密,而第二種是對一組明文使用密鑰進行加密。
先來看看分組加密的工做模式。
1. ECB:電子密碼本(最經常使用的,每次加密均產生獨立的密文分組,而且對其餘的密文分組不會產生影響,也就是相同的明文加密後產生相同的密文) 2. CBC:密文連接(經常使用的,明文加密前須要先和前面的密文進行異或運算,也就是相同的明文加密後產生不一樣的密文) 除了這兩種經常使用的工做模式,還有: 3. CFB:密文反饋 4. OFB:輸出反饋 5. CTR:計數器
1. NoPadding:無填充 2. PKCS5Padding: 3. ISO10126Padding
經常使用的加密方式DES、3DES、AES。能夠來對比一下,這幾個算法的區別。
由於BASE64的加密解密算法是公開的,因此加密數據是沒有任何安全性可言。先來看看API文檔中提供的BASE64加密的類。除了在JDK中內置的也有一些第三方類會提供BASE64加密的類。
package com.demo; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.IOException; public class base64demo { public static void main(String[] args) throws IOException { String name = "xiaoming"; BASE64Encoder encoder = new BASE64Encoder//實例化BASE64Encoder對象 String encode = encoder.encode(name.getBytes());//調用encode進行加密 System.out.println(encode); BASE64Decoder base64Decoder = new BASE64Decoder();//實例化BASE64Decoder對象 byte[] bytes = base64Decoder.decodeBuffer(encode);//進行解密 System.out.println(bytes); String s = new String(bytes); System.out.println(s); } }
BASE64的加解密比較簡單,在這裏就不細說了。
DES的算法其實已經被公開了,實際上是不太安全的。
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.spec.DESKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; public class desdemo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { //1.生成密鑰 KeyGenerator des = KeyGenerator.getInstance("DES");//設置獲取des的密鑰 des.init(56);//初始化密鑰生成器,設置爲56長度的密鑰 SecretKey secretKey = des.generateKey();//獲取密鑰 // System.out.println(secretKey); byte[] deskey = secretKey.getEncoded(); //獲取密鑰的byte數組 //2.密鑰轉換 DESKeySpec desKeySpec = new DESKeySpec(deskey); SecretKeyFactory des1 = SecretKeyFactory.getInstance("DES"); SecretKey secretKey1 = des1.generateSecret(desKeySpec); // System.out.println(secretKey1); //3.加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");//選擇算法、工做模式和填充方式 cipher.init(Cipher.ENCRYPT_MODE,secretKey1);//選擇加密模式和密鑰進行加密 byte[] res = cipher.doFinal(name.getBytes());//加密數據 // System.out.println(res); // String s = new String(res); System.out.println(HexBin.encode(res));//輸出加密後結果 //4.解密 cipher.init(Cipher.DECRYPT_MODE,secretKey1);//選擇密鑰,並使用解密模式 byte[] bytes = cipher.doFinal(res);//解密加密後的結果 String s1 = new String(bytes); System.out.println(s1); } }
3DES也被叫作DESede,也就是基於DES三次加密。其實也有四層和兩層DES,可是平時中用的最多的仍是3DES。
上面的圖是他的一個算法的說明圖。
其實3DES和DES在代碼中的實現方式很類似。可是要注意的一點是密鑰長度要選擇正確,不然會報錯。或者是可使用SecureRandom()
類,讓他根據選擇的加密算法使用默認的密鑰長度。
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; public class jdk3des { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { //1.生成密鑰 KeyGenerator des = KeyGenerator.getInstance("DESede");//設置獲取des的密鑰 // des.init(168);//初始化密鑰生成器,設置爲168長度的密鑰 des.init(new SecureRandom());//根據加密算法使用默認密鑰長度 SecretKey secretKey = des.generateKey();//獲取密鑰 // System.out.println(secretKey); byte[] deskey = secretKey.getEncoded(); //獲取密鑰的byte數組 //2.密鑰轉換 DESedeKeySpec desKeySpec = new DESedeKeySpec(deskey); SecretKeyFactory des1 = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey1 = des1.generateSecret(desKeySpec); // System.out.println(secretKey1); //3.加密 Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");//選擇算法、工做模式和填充方式 cipher.init(Cipher.ENCRYPT_MODE,secretKey1);//選擇加密模式和密鑰進行加密 byte[] res = cipher.doFinal(name.getBytes());//加密數據 // System.out.println(res); // String s = new String(res); System.out.println(HexBin.encode(res));//輸出加密後結果 //4.解密 cipher.init(Cipher.DECRYPT_MODE,secretKey1);//選擇密鑰,並使用解密模式 byte[] bytes = cipher.doFinal(res);//解密加密後的結果 String s1 = new String(bytes); System.out.println(s1); } }
AES是目前用的最多的對稱加密算法,通常用於移動通信系統加密或者是基於SSH協議的軟件
AES的填充方式有三種:
(PKCS7Padding/PKCS5Padding/ZeroPadding)
PKCS7Padding跟PKCS5Padding的區別就在於數據填充方式,PKCS7Padding是缺幾個字節就補幾個字節的0,而PKCS5Padding是缺幾個字節就補充幾個字節的幾,好比缺6個字節,就補充6個字節的6。
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import com.sun.xml.internal.messaging.saaj.util.Base64; import sun.misc.BASE64Encoder; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class aesdemo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { //1.獲取密鑰 KeyGenerator aes = KeyGenerator.getInstance("AES"); aes.init(128); SecretKey secretKey = aes.generateKey(); byte[] encoded = secretKey.getEncoded(); //2.密鑰轉換 Key key = new SecretKeySpec(encoded, "AES"); //3.加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE,key); byte[] bytes = cipher.doFinal(name.getBytes()); System.out.println(new BASE64Encoder().encode(bytes));//加密完成後,再使用base64進行加密 //4.解密 cipher.init(Cipher.DECRYPT_MODE,key); byte[] bytes1 = cipher.doFinal(bytes); System.out.println(new String(bytes1)); } }
下面來放一張基於AES加解密的流程圖。
PBE算法(Password Based Encryption,基於口令加密)是一種基於口令的加密算法,其特色是使用口令代替了密鑰,而口令由用戶本身掌管,採用隨機數雜湊多重加密等方法保證數據的安全性。PBE算法在加密過程當中並非直接使用口令來加密,而是加密的密鑰由口令生成,這個功能由PBE算法中的KDF函數完成。KDF函數的實現過程爲:將用戶輸入的口令首先經過「鹽」(salt)的擾亂產生準密鑰,再將準密鑰通過散列函數屢次迭代後生成最終加密密鑰,密鑰生成後,PBE算法再選用對稱加密算法對數據進行加密,能夠選擇DES、3DES、RC5等對稱加密算法
以上這張圖是PBE算法的實現方式
package com.demo; import com.sun.xml.internal.messaging.saaj.util.Base64; import sun.misc.BASE64Encoder; import javax.crypto.*; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import java.security.*; import java.security.spec.InvalidKeySpecException; public class pbedemo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException { //1.初始化鹽 SecureRandom secureRandom = new SecureRandom(); byte[] salt = secureRandom.generateSeed(8); //2. 獲取密鑰 String password = "123456"; PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES"); Key key = factory.generateSecret(pbeKeySpec); //3.加密 PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100); Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); cipher.init(Cipher.ENCRYPT_MODE,key,pbeParameterSpec); byte[] bytes = cipher.doFinal(name.getBytes()); System.out.println(new BASE64Encoder().encode(bytes)); //4.解密 cipher.init(Cipher.DECRYPT_MODE,key,pbeParameterSpec); byte[] res = cipher.doFinal(bytes); System.out.println(new String(res)); } }
非對稱加密算法須要兩個密鑰:公鑰和私鑰。公鑰]與私鑰是一對,若是用公鑰對數據進行加密,只有用對應的私鑰才能解密。由於加密和解密使用的是兩個不一樣的密鑰,因此這種算法叫做非對稱加密算法。
1976年非對稱加密算法思想被提出,可是當時並無給出具體算法和方案,由於當時沒有研究出單向函數
(也就是信息摘要算法還沒出現),可是IEEE的期刊中給出了通訊時雙方如何經過信息交換協商密鑰
的算法,也就是DH算法,經過該算法雙方能夠協商對稱加密的密鑰。
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; public class dhdemo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { // 1.初始化發送方密鑰 KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH"); sendKeyPairGenerator.initialize(512); KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair(); byte[] sendPublicKeyEnc = sendKeyPair.getPublic().getEncoded();//生成發送方公鑰,發送給接收方(網絡、文件...) // 2.初始化接收方密鑰: KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(sendPublicKeyEnc); PublicKey receivePublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec = ((DHPublicKey)receivePublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate(); byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded(); // 3.構建接收方密鑰: KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH"); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receivePublicKey, true); SecretKey receiverDESKey = receiverKeyAgreement.generateSecret("DES");//接收方Key // 4.構建發送方密鑰: KeyFactory sendKeyFactory = KeyFactory.getInstance("DH"); x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc); PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH"); sendKeyAgreement.init(sendKeyPair.getPrivate()); sendKeyAgreement.doPhase(sendPublicKey, true); SecretKey sendDESKey = sendKeyAgreement.generateSecret("DES");//發送方Key // 5.發送方加密: Cipher sendCipher = Cipher.getInstance("DES"); sendCipher.init(Cipher.ENCRYPT_MODE, sendDESKey); byte[] sendResult = sendCipher.doFinal(name.getBytes()); System.out.println("sendResult :"+ HexBin.encode(sendResult)); // 6.接收方解密: Cipher receiverCipher = Cipher.getInstance("DES"); receiverCipher.init(Cipher.DECRYPT_MODE, receiverDESKey); byte[] receiverResult = receiverCipher.doFinal(sendResult); System.out.println("receiverResult : "+new String (receiverResult)); } }
RSA公開密鑰密碼體制是一種使用不一樣的加密密鑰與解密密鑰,「由已知加密密鑰推導出解密密鑰在計算上是不可行的」密碼體制。RSA算法實現了公鑰加密、私鑰解密 和私鑰解密、公鑰加密的一個機制。
也就是說使用公鑰來進行加密,想要解密獲取明文內容,就必須使用對應的私鑰來進行解密。而在其中私鑰中的內容實際上是比較長的,而公鑰裏面的內容會偏短一些。由於私鑰通常會儲存在本地,而公鑰會放到各大互聯網上,公鑰比私鑰內容短也是爲了方便傳輸和存儲。
package com.demo; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import sun.misc.BASE64Encoder; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class rsademo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { // 1.初始化密鑰 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//設置獲取RSA的密鑰 keyPairGenerator.initialize(512);//設置密鑰長度 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密鑰對 RSAPublicKey rsaPublic =(RSAPublicKey) keyPair.getPublic();//獲取公鑰 RSAPrivateKey rsaPrivate = (RSAPrivateKey)keyPair.getPrivate();//獲取私鑰 // System.out.println(new BASE64Encoder().encode(rsaPublic.getEncoded()));//輸出公鑰 System.out.println(""); // System.out.println(new BASE64Encoder().encode(rsaPrivate.getEncoded()));//輸出私鑰 // 2.私鑰加密、公鑰解密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());//對密鑰進行編碼處理 KeyFactory rsa = KeyFactory.getInstance("RSA");//設置獲取RSA的密鑰 PrivateKey privateKey = rsa.generatePrivate(pkcs8EncodedKeySpec);//從提供的密鑰規範生成私鑰對象。 // 2.1私鑰加密 Cipher encodecipher = Cipher.getInstance("RSA");//設置獲取RSA的密鑰 encodecipher.init(Cipher.ENCRYPT_MODE,privateKey);//設置爲加密類型並傳入私鑰進行加密 byte[] res = encodecipher.doFinal(name.getBytes());//對內容進行加密 System.out.println(new BASE64Encoder().encode(res)); // 2.2公鑰解密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublic.getEncoded());//對公鑰進行編碼處理 rsa = KeyFactory.getInstance("RSA");//設置獲取RSA的密鑰 PublicKey publicKey = rsa.generatePublic(x509EncodedKeySpec);//從提供的密鑰規範生成公鑰對象。 Cipher decodecipher = Cipher.getInstance("RSA");//設置獲取RSA的密鑰 decodecipher.init(Cipher.DECRYPT_MODE,publicKey);//設置解密類型並傳入公鑰進行解密 byte[] decoderes = decodecipher.doFinal(res);//對內容進行解密 System.out.println(new String(decoderes)); } }
下面再來看個公鑰加密私鑰解密的代碼
package com.demo; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import sun.misc.BASE64Encoder; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class rsademo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { // 1.初始化密鑰 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//設置獲取RSA的密鑰 keyPairGenerator.initialize(512);//設置密鑰長度 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密鑰對 RSAPublicKey rsaPublic =(RSAPublicKey) keyPair.getPublic();//獲取公鑰 RSAPrivateKey rsaPrivate = (RSAPrivateKey)keyPair.getPrivate();//獲取私鑰 // System.out.println(new BASE64Encoder().encode(rsaPublic.getEncoded()));//輸出公鑰 System.out.println(""); // 3.公鑰加密、私鑰解密 // 3.1公鑰加密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublic.getEncoded()); KeyFactory encodersa = KeyFactory.getInstance("RSA"); PublicKey publicKey = encodersa.generatePublic(x509EncodedKeySpec); Cipher encodecipher = Cipher.getInstance("RSA"); encodecipher.init(Cipher.ENCRYPT_MODE,publicKey); byte[] encoderes = encodecipher.doFinal(name.getBytes()); System.out.println(new BASE64Encoder().encode(encoderes)); // 3.2私鑰解密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivate.getEncoded()); KeyFactory decodersa = KeyFactory.getInstance("RSA"); PrivateKey privateKey = decodersa.generatePrivate(pkcs8EncodedKeySpec); Cipher decodecipher = Cipher.getInstance("RSA"); decodecipher.init(Cipher.DECRYPT_MODE,privateKey); byte[] decoderes = decodecipher.doFinal(encoderes); System.out.println(new String(decoderes)); } }
在代碼中其實能夠看到用到了x509EncodedKeySpec
和pkcs8EncodedKeySpec
的類,其實這兩個類一個用於對私鑰進行編碼的,一個是對私鑰進行編碼。
在安全中其實加密算法顯得格外的重要,舉個例子,好比說冰蠍,爲何就能過一些設備呢?其實分析過冰蠍的,或者是看過冰蠍做者大大的文章的應該會知道,冰蠍在流量傳輸中也是作了加密的。使用的是AES加密。首先是將客戶端發送的命令轉換成字節碼,而後使用aes進行加密,而後在客戶端也就是webshell獲取密鑰進行解密獲得字節碼,最後就是使用defineClass來動態加載字節碼進行執行。
可是在後面各大廠商的設備隨着各大廠商設備的不斷升級,冰蠍2仍是被殺了。這是由於在冰蠍aes傳輸密鑰的時候被識別出來了。那麼咱們若是再對該密鑰進行更狠一點加密呢?雖說也能實現,步驟繁瑣一些。可是這仍是會產生一些流量。在冰蠍3中的作法是去除了握手的過程,直接寫死在Webshell中的字符串做爲AES密鑰解密流量包。
後面打算基於冰蠍進行一個重寫,並使用不一樣的算法來實現加密。