常用加密解密演算法【RSA、AES、DES、MD5】介紹和使用
為了防止我們的資料洩露,我們往往會對資料進行加密,特別是敏感資料,我們要求的安全性更高。下面將介紹幾種常用的加密演算法使用。這些演算法的加密物件都是基於二進位制資料,如果要加密字串就使用統一編碼(如:utf8)進行編碼後加密。
1.摘要演算法
常用的摘要演算法有MD5,SHA1。摘要演算法是一個不可逆過程,就是無論多大資料,經過演算法運算後都是生成固定長度的資料,一般結果使用16進位制進行顯示。
MD5和SHA1的區別:MD5結果是128位摘要,SHa1是160位摘要。那麼MD5的速度更快,而SHA1的強度更高。
下面統一使用MD5演算法進行說明,SHA1類似。
主要用途有:驗證訊息完整性,安全訪問認證,資料簽名。
- 訊息完整性:由於每一份資料生成的MD5值不一樣,因此傳送資料時可以將資料和其MD5值一起傳送,然後就可以用MD5驗證資料是否丟失、修改。
- 安全訪問認證:這是使用了演算法的不可逆性質,(就是無法從MD5值中恢復原資料)對賬號登陸的密碼進行MD5運算然後儲存,這樣可以保證除了使用者之外,即使資料庫管理人員都無法得知使用者的密碼。
- 數字簽名:這是結合非對稱加密演算法和CA證照的一種使用場景。
一般破解方法:字典法,就是將常用密碼生成MD5值字典,然後反向查詢達到破解目的,因此建議使用強密碼。
MD5的使用—對檔案進行摘要。
//對檔案進行MD5摘要
public static String getMD5(String path){
String pathName = path;
String md5= "";
try {
File file = new File(pathName);
FileInputStream ins = new FileInputStream(file);
FileChannel ch = ins.getChannel();
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,file.length());
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(byteBuffer);
ins.close();
md5 = toHexString(md.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return md5;
}
//以16進位制編碼進行輸出
final static char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String toHexString(byte[] tmp){
String s;
char str[] = new char[tmp.length*2];
int k =0;
for (int i = 0; i < tmp.length; i++) {
byte byte0 = tmp[i];
str[k++] = hex[byte0>>>4&0xf];
str[k++] = hex[byte0&0xf];
}
s=new String(str);
return s;
}
SHA1的使用
//對檔案進行SHA1摘要
public static String getSHA1(String path){
String pathName = path;
String sha1= "";
try {
File file = new File(pathName);
FileInputStream ins = new FileInputStream(file);
FileChannel ch = ins.getChannel();
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,file.length());
MessageDigest sha = MessageDigest.getInstance("SHA-1");
sha.update(byteBuffer);
ins.close();
sha1 = toHexString(sha.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sha1;
}
可以發現我們的關鍵程式碼就是
MessageDigest sha = MessageDigest.getInstance("SHA-1");
sha.update(byteBuffer);
ins.close();
byte[] r = sha.digest());
只是不同的演算法初始化時不同罷了。MessageDigest.getInstance("SHA-1")
另外還可以使用
DigestUtils.sha1(data);
DigestUtils.md5Hex(data);
上面實現使用的是Apache下面的一個加解密開發包commons-codec
官方地址為:http://commons.apache.org/codec/
官方下載地址:http://commons.apache.org/codec/download_codec.cgi
2.對稱加密演算法
對稱加密演算法只是為了區分非對稱加密演算法。其中鮮明的特點是對稱加密是加密解密使用相同的金鑰,而非對稱加密加密和解密時使用的金鑰不一樣。對於大部分情況我們都使用對稱加密,而對稱加密的金鑰交換時使用非對稱加密,這有效保護金鑰的安全。非對稱加密加密和解密金鑰不同,那麼它的安全性是無疑最高的,但是它加密解密的速度很慢,不適合對大資料加密。而對稱加密加密速度快,因此混合使用最好。
常用的對稱加密演算法有:AES和DES.
- DES:比較老的演算法,一共有三個引數入口(原文,金鑰,加密模式)。而3DES只是DES的一種模式,是以DES為基礎更安全的變形,對資料進行了三次加密,也是被指定為AES的過渡演算法。
- AES:高階加密標準,新一代標準,加密速度更快,安全性更高(不用說優先選擇)
AES的使用
AES金鑰長度可以選擇128位【16位元組】,192位【24位元組】和256位【32位元組】金鑰(其他不行,因此別亂設密碼哦)。
/**使用AES對字串加密
* @param str utf8編碼的字串
* @param key 金鑰(16位元組)
* @return 加密結果
* @throws Exception
*/
public static byte[] aesEncrypt(String str, String key) throws Exception {
if (str == null || key == null) return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
return bytes;
}
/**使用AES對資料解密
* @param bytes utf8編碼的二進位制資料
* @param key 金鑰(16位元組)
* @return 解密結果
* @throws Exception
*/
public static String aesDecrypt(byte[] bytes, String key) throws Exception {
if (bytes == null || key == null) return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
bytes = cipher.doFinal(bytes);
return new String(bytes, "utf-8");
}
上面程式碼是對字串進行的加解密。但要注意的是AES演算法的所有引數都是位元組碼的(包括金鑰)。因此字串字元需要轉換成位元組碼後進行加密str.getBytes("utf-8")
按照字串的編碼進行轉換。另外引數:”AES/ECB/PKCS5Padding”在加密和解密時必須相同,可以直接寫”AES”,這樣就是使用預設模式(C#和java預設的模式不一樣,C#中預設的是這種,java的預設待研究)。分別的意思為:AES是加密演算法,ECB是工作模式,PKCS5Padding是填充方式。
AES是分組加密演算法,也稱塊加密。每一組16位元組。這樣明文就會分成多塊。當有一塊不足16位元組時就會進行填充。
一共有四種工作模式:
- ECB 電子密碼本模式:相同的明文塊產生相同的密文塊,容易並行運算,但也可能對明文進行攻擊。
- CBC 加密分組連結模式:一塊明文加密後和上一塊密文進行連結,不利於並行,但安全性比ECB好,是SSL,IPSec的標準。
- CFB 加密反饋模式:將上一次密文與金鑰運算,再加密。隱藏明文模式,不利於並行,誤差傳遞。
- OFB 輸出反饋模式:將上一次處理過的金鑰與金鑰運算,再加密。隱藏明文模式,不利於並行,有可能明文攻擊,誤差傳遞。
PKCS5Padding的填充方式是差多少位元組就填數字多少;剛好每一不足16位元組時,那麼就會加一組填充為16.還有其他填充模式【Nopadding,ISO10126Padding】(不影響演算法,加密解密時一致就行)。
DES的使用
和AES類似,指定為DES就行。3DES指定為”DESede”,DES金鑰長度是56位,3DES加長了金鑰長度,可以為112位或168位,所以安全性提高,速度降低。工作模式和填充模式標準和AES一樣。
/**使用DES對字串加密
* @param str utf8編碼的字串
* @param key 金鑰(56位,7位元組)
* @return 加密結果
* @throws Exception
*/
public static byte[] desEncrypt(String str, String key) throws Exception {
if (str == null || key == null) return null;
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "DES"));
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
return bytes;
}
/**使用DES對資料解密
* @param bytes utf8編碼的二進位制資料
* @param key 金鑰(16位元組)
* @return 解密結果
* @throws Exception
*/
public static String desDecrypt(byte[] bytes, String key) throws Exception {
if (bytes == null || key == null) return null;
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "DES"));
bytes = cipher.doFinal(bytes);
return new String(bytes, "utf-8");
}
3.非對稱加密(RSA)
這裡主要對RSA進行介紹。
對稱加密加密解密使用的是相同的金鑰,而非對稱加密加密解密時使用的不同的金鑰,分為公鑰(public key)和私鑰(private key).公鑰可以公開,而私鑰自己儲存。它利用的是兩個大質數相乘十分容易,而對其乘積進行因素分解十分困難。這樣就可以將乘積作為金鑰了,這個乘積為N值,根據兩個大質數選擇e和生成d,刪掉兩個大質數。這樣(N,e)為公鑰,(N,d)為私鑰,公鑰無法破解出私鑰(不作詳細介紹,我們不是研究演算法的)。由於非對稱加密的金鑰生成麻煩,所以無法做到一次一密,而且其加密速度很慢,無法對大量資料加密。因此最常用的使用場景就是數字簽名和密碼傳輸,用作數字簽名時使用私鑰加密,公鑰解密;用作加密解密時,使用公鑰加密,私鑰解密。
需要注意的是RSA加密是有長度限制的,1024位金鑰可以加密128位元組(1024位),不滿128位元組的使用隨機數填充,但是RSA實現中必須要加隨機數(11位元組以上),所以明文長度最大為117位元組,然後剩下的加入隨機數。這也產生了每次加密結果每一次都不一樣的特點。
如果明文長度超過限制怎麼辦?
- 1.可以與對稱加密混合使用,一次一密產生對稱加密的金鑰,然後使用此金鑰進行資料對稱加密,再使用RSA私鑰對對稱金鑰加密,一起儲存。解密時使用公鑰解密出金鑰,然後進行資料解密。
- 2.可以分段加密。將明文按117位元組分成多段,加密後再拼接起來。由於每一段密文長度都是128位元組,所以解密時按照128位元組分段解密。
java的RSA金鑰生成與使用
簡單使用
下面是java中的使用方法,先是生成金鑰對,然後加密,再解密。需要注意的是這個方法是不能跨語言使用的,因為裡面對公鑰和私鑰用到的序列化是java的序列化。
由於加密後的密文都是位元組碼形式的,我們要以字串方式儲存或傳輸的話,可以使用Base64編碼。
public class RSAUtil {
/** 指定加密演算法為RSA */
private static String ALGORITHM = "RSA";
/*指定加密模式和填充方式*/
private static String ALGORITHM_MODEL = "RSA/ECB/PKCS1Padding";
/** 指定key的大小,一般為1024,越大安全性越高 */
private static int KEYSIZE = 1024;
/** 指定公鑰存放檔案 */
private static String PUBLIC_KEY_FILE = "PublicKey";
/** 指定私鑰存放檔案 */
private static String PRIVATE_KEY_FILE = "PrivateKey";
/**
* 生成金鑰對
*/
private static void generateKeyPair() throws Exception {
/** RSA演算法要求有一個可信任的隨機數源 */
SecureRandom sr = new SecureRandom();
/** 為RSA演算法建立一個KeyPairGenerator物件 */
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
/** 利用上面的隨機資料來源初始化這個KeyPairGenerator物件 */
kpg.initialize(KEYSIZE, sr);
/** 生成密匙對 */
KeyPair kp = kpg.generateKeyPair();
/** 得到公鑰 */
Key publicKey = kp.getPublic();
/** 得到私鑰 */
Key privateKey = kp.getPrivate();
/** 用物件流將生成的金鑰寫入檔案 */
ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(
PUBLIC_KEY_FILE));
ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(
PRIVATE_KEY_FILE));
oos1.writeObject(publicKey);
oos2.writeObject(privateKey);
/** 清空快取,關閉檔案輸出流 */
oos1.close();
oos2.close();
}
/**
* 加密方法 source: 源資料
*/
public static byte[] encrypt(String source) throws Exception {
/** 將檔案中的公鑰物件讀出 */
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
PUBLIC_KEY_FILE));
Key key = (Key) ois.readObject();
ois.close();
/** 得到Cipher物件來實現對源資料的RSA加密 */
Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] b = source.getBytes();
/** 執行加密操作 */
byte[] b1 = cipher.doFinal(b);
return b1;
}
/**
* 解密演算法 cryptograph:密文
*/
public static String decrypt(byte[] cryptograph) throws Exception {
/** 將檔案中的私鑰物件讀出 */
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
PRIVATE_KEY_FILE));
Key key = (Key) ois.readObject();
/** 得到Cipher物件對已用公鑰加密的資料進行RSA解密 */
Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL);
cipher.init(Cipher.DECRYPT_MODE, key);
/** 執行解密操作 */
byte[] b = cipher.doFinal(cryptograph);
return new String(b);
}
public static void main(String[] args) throws Exception {
generateKeyPair();//生成金鑰對
String source = "Hello World!";// 要加密的字串
byte[] cryptograph = encrypt(source);// 生成的密文
//可以將密文進行base64編碼進行傳輸
System.out.println(new String(Base64.encode(cryptograph)));
String target = decrypt(cryptograph);// 解密密文
System.out.println(target);
}
}
RSA金鑰使用Base64編碼
要靈活使用肯定不能使用java的序列化儲存了,我們對上面的generateKeyPair()方法進行改寫。通過金鑰生成器生成公鑰,私鑰後,呼叫publicKey.getEncoded()和privateKey.getEncoded()
,此時它生成的位元編碼是有獨特格式的(公鑰是X.509,私鑰是PKCS#8)可以使用publicKey.getFormat(),privateKey.getFormat();
進行檢視。之後對位元組碼進行Base64編碼就行了。
金鑰生成方法
//以base64編碼金鑰
public Map<String ,String> generateKeyPair1() throws Exception{
SecureRandom sr = new SecureRandom();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024, sr);
KeyPair kp = kpg.generateKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
byte[] pb = publicKey.getEncoded();
String pbStr = new String(Base64.encode(pb));
byte[] pr = privateKey.getEncoded();
String prStr = new String(Base64.encode(pr));
Map<String, String> map = new HashMap<String, String>();
map.put("publicKey",pbStr);
map.put("privateKey", prStr);
return map;
}
恢復金鑰方法,使用各自不同的編碼形式恢復
//從base64編碼的公鑰恢復公鑰
public PublicKey getPulbickey(String key_base64) throws Exception{
byte[] pb = Base64.decode(key_base64).getBytes();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pb);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
return keyfactory.generatePublic(keySpec);
}
//從base64編碼的私鑰恢復私鑰
public PrivateKey getPrivatekey(String key_base64) throws Exception{
byte[] pb = Base64.decode(key_base64).getBytes();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pb);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
return keyfactory.generatePrivate(keySpec);
}
加密解密方法都類似下面,PrivateKey和PublicKey是Key的子介面。
/** 執行加密操作 */
public static byte[] encrypt(Key key,byte[] source) throws Exception{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] ciphertext = cipher.doFinal(source);
return ciphertext;
}
/** 執行加密操作 */
public static byte[] decrypt(Key key,byte[] ciphertext) throws Exception{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] source = cipher.doFinal(ciphertext);
return source;
}
記錄RSA的金鑰特徵值並進行密碼恢復
所謂特徵值就是RSA中公鑰(N,e)私鑰(N,d)的三個值:N,e,d。只要有這三個值我們就可以恢復金鑰了。這是實際開發中常用的方法。首先是提取特徵值,我們需要將PublicKey強制轉換為RSAPublicKey.然後獲取,看程式碼。
//提取特徵值儲存,以base64編碼金鑰
public static Map<String ,String> generateKeyPair2() throws Exception{
SecureRandom sr = new SecureRandom();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024, sr);
KeyPair kp = kpg.generateKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
RSAPublicKey rpk = (RSAPublicKey)publicKey;
RSAPrivateKey rpr= (RSAPrivateKey)privateKey;
//三個特徵值都是BigInteger型別。
BigInteger N = rpk.getModulus();//N值
BigInteger e = rpk.getPublicExponent();//e值
BigInteger d = rpr.getPrivateExponent();//d值
Map<String, String> map = new HashMap<String, String>();
//將BigInteger轉為byte[],然後以base64儲存
map.put("N",new String(Base64.decode(N.toByteArray())));
map.put("e", new String(Base64.decode(e.toByteArray())));
map.put("d", new String(Base64.decode(d.toByteArray())));
return map;
}
利用三個特徵值就可以非常容易恢復金鑰了。
//從base64編碼的特徵值(N,e)恢復公鑰
public static PublicKey getPulbickey(String N_Str,String e_Str) throws Exception{
BigInteger N = new BigInteger(1, Base64.decode(N_Str.getBytes()));
BigInteger e = new BigInteger(1, Base64.decode(e_Str.getBytes()));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec ps = new RSAPublicKeySpec(N, e);
PublicKey pkey = kf.generatePublic(ps);
return pkey;
}
//從base64編碼的特徵值(N,d)恢復私鑰
public static PrivateKey getPrivatekey(String N_Str,String d_Str) throws Exception{
BigInteger N = new BigInteger(1, Base64.decode(N_Str.getBytes()));
BigInteger d = new BigInteger(1, Base64.decode(d_Str.getBytes()));
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec ps = new RSAPrivateKeySpec(N, d);
PrivateKey pkey = kf.generatePrivate(ps);
return pkey;
}
C#生成的金鑰java中使用–記錄特徵值的例子
C#生成的公鑰是儲存在xml檔案中的,使用的是Base64編碼,因此我們先解析出金鑰物件,然後再使用公鑰加密,而讓C#端伺服器進行解密。Modulus就是N值,Exponent就是e值,然後組成(N,e)公鑰。
C#的金鑰形式如:
<RSAKeyValue>
<Modulus>7gFGAUTUBiSi8j+oZ4JY4NUNCfdGIxFLhKE0c4SbiHvNAiD7rxWnmuqXK4nVzOyjJsmCViA1aRN3+Tf5xMqxtjjCKWNRWAp5LMp2AfL3DrDcWV/ZjwPIUO52yEa+q2PyJ0OMgRxBA80WWBzv+EJm7/rq8wP9gpVI+HY0ACH8Kmk=
</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
//從xml中獲取公鑰
public static PublicKey getPublicKey(String xmlkey) throws Exception {
Document doc = XmlUtil.parseXml(xmlkey);
Node node = doc.getChildNodes().item(0);
NodeList list = node.getChildNodes();
String e = null, m = null;
for (int i = 0; i < list.getLength(); i++) {
String nodename = list.item(i).getNodeName();
String value = list.item(i).getTextContent();
if (nodename.equals("Modulus")) {
e = value;
} else if (nodename.equals("Exponent")) {
m = value;
}
}
BigInteger b1 = new BigInteger(1, Base64.decode(e.getBytes()));
BigInteger b2 = new BigInteger(1, Base64.decode(m.getBytes()));
System.out.println(b1 + "\n" + b2);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec ps = new RSAPublicKeySpec(b1, b2);
PublicKey pkey = kf.generatePublic(ps);
return pkey;
}
//RSA加密
public static byte[] encrypt(byte[] data,PublicKey publickey) {
if (publickey == null || data == null) {
return null;
}
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publickey);
return cipher.doFinal(data);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//字串轉Document
public static Document parseXml(String str) throws ParserConfigurationException, SAXException, IOException{
StringReader reader = new StringReader(str);
InputSource source = new InputSource(reader);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(source);
}
4.編碼的使用
常見的編碼有Base64,HEX和對URL的編碼。這都是為了實際需要才進行的編碼。HEX是編碼成16進位制字元,MD5一般就是以HEX進行編碼,這不說了。
Base64
Base64一開始是為了解決郵件中不能傳檔案和圖片問題而使用的,將無法閱讀的二進位制碼轉化成字元形式,字元為(A-Za-z0-9+/)。它的原理是將3個8位位元組(24位)轉化為4個6位位元組(24位),之後在6位的前面補兩個0,形成8位一個位元組形式,如果剩下的不足3位元組,則用0填充,輸出字元使用”=”,所以編碼後文字可能出現1個或2個’=’.這樣就將原本3個位元組變成了4個位元組,那就是64種編碼了。當然,除了對二進位制資料編碼,還可以對字串編碼來隱藏明文,讓別人不那麼容易看懂。
由於jdk中的base64是不開發使用了 ,所有需要下載到網上下載Base64包,我使用的是 javaBase64-1.2.jar,另外android sdk中是帶有base64的,位置是android.util.Base64
/*這裡使用的是android.util.base64*/
byte[] input = "hello world".getBytes("utf8");
//編碼
byte[] encodeData = Base64.encode(input , 0);
//解碼
byte[] result = Base64.decode(encodeData , 0);
URL的編碼
url一般使用的都是英文、數字和某些符號,而對於特殊符號,中文等這些是不允許使用的。因此我們要在url請求中加入特殊符號,中文等就需要對它們進行編碼。http請求時,url部分是必須編碼的,get的請求欄位可以不進行url編碼。比如
http://www.baidu.com/中文?wd=國際
“中文”必須進行url編碼,“國際”可以不用。
那url編碼到底是怎麼進行編碼的呢?
都是在16進位制前面加上‘%’表示。對於一些字元使用的是”%xx”,而對於中文,就是多個”%xx%xx%xx”,xx的數字有編碼的16進位制決定(沒有指定字元編碼(utf8),則使用預設編碼),然後每一位元組前面加”%”。
Android 中提供的URL編碼解碼方法。
String d = URLEncoder.encode('中文',"utf8");
String f = URLDecoder.decode("%20");
RSA參考文章:
【1】 RSA演算法使用介紹
【2】使用X.509數字證照加密解密實務(二)– 證照的獲得和管理
相關文章
- nodejs常用加密方式 RSA & AESNodeJS加密
- RSA der加密 p12解密以及配合AES使用詳解加密解密
- AES 加密演算法的詳細介紹加密演算法
- AES加密解密加密解密
- AES 加密&解密加密解密
- php中aes加密和rsa加密的區別PHP加密
- AES CBC 加密解密加密解密
- RSA加密與解密加密解密
- Java實現AES和RSA演算法Java演算法
- python怎麼使用md5加密解密Python加密解密
- RSA加密演算法簡單介紹以及python實現加密演算法Python
- 安全篇-AES/RSA加密機制加密
- Python AES 加密和解密(qbit)Python加密解密
- golang AES-CBC 加密解密Golang加密解密
- python AES-CBC 加密解密Python加密解密
- Java 常用加密解密演算法Java加密解密演算法
- Python使用AES進行鹽值加密和解密Python加密解密
- Java AES加密和解密教程 - BaeldungJava加密解密
- 密碼學之DES/AES演算法密碼學演算法
- AES和DES程式碼實現
- C# MD5 加密,解密C#加密解密
- php rsa長文加密解密PHP加密解密
- RSA 非對稱加密&解密加密解密
- JavaScript前端和Java後端的AES加密和解密JavaScript前端後端加密解密
- AES位元組陣列加密解密流程陣列加密解密
- delphi加密C#解密(AES-256)加密C#解密
- RSA加密解密示例程式碼加密解密
- Golang 裡的 AES、DES、3DES 加解密,支援 ECB、CBC 等多種模式組合Golang3D解密模式
- 在VUE中使用RSA加密解密加簽解籤Vue加密解密
- 10:c# mds5與des與rsa加密C#加密
- AES線上加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各種加密解密原始碼加密解密原始碼
- 簡話密碼學3 - 常用加密演算法介紹密碼學加密演算法
- 告別DES 迎接AES
- C/C++ 常用加密與解密演算法C++加密解密演算法
- Vue使用AES加密Vue加密
- MD5介紹
- PHP中RSA加密演算法的使用PHP加密演算法
- RSA加密演算法加密演算法
- JavaScript實現的base64加密、md5加密、sha1加密及AES加密JavaScript加密