(原)
常用的加密有3種
1、正向加密,如MD5,加密后密文固定,目前還沒辦法破解,但是可以能過數據庫撞庫有一定概率找到,不過現在一般用這種方式加密都會加上鹽值。
2、對稱加密,通過一個固定的對稱密鑰,對需要傳輸的數據進行加解密,速度快,但是安全性不高,主要用於企業級內部系統中數據傳輸。
3、非對稱加密,N把公鑰,一把私鑰,私鑰存放在服務器一方保管,公鑰放可以放在任何一個客戶端,客戶端向服務器請求的密文只有拿到了私鑰的服務器一端可以解密。
這里有個概念解釋一下,
隨機鹽值(solt):
abcd -> MD5加密 -> E2FC714C4727EE9395F324CD2E7F331F
然后通過撞庫的方式,這種簡單的字符一般都能很快的被找到

如果我定義一個只有自己知道的字符串,放在要加密的文的任何地方,比如我在abcd第二個字符前加上:helloword123123,那么要加密的字符就變成了:ahelloword123123worldbcd。
我們對這個再次進行加密:
ahelloword123123worldbcd -> MD5加密 -> 978E1014EEFF5E0A708314DB2E7D6DA1
我們再次通過撞庫的方式來解密:

發現這次再通過撞庫的方式解密失敗了。這里的鹽值的作用相當於擾亂了正常要加密的字符,而這個規律只有開發者,服務端的人知道。
^(異或)運算的作用。
它的運算規則是二進制運算中,相同得0,不同得1,如:2的二進制是10,3的二進制是11,最后得到的結果是01,轉成十進制就是1。
如圖:

異或運算還有一個特殊的性質,就是逆運算,就拿剛才的例子來說,2^3=1,無論2、3、1中哪二個數做異或,結果永遠只會等於另一個數。
比如:
2^3=1
2^1=3
3^1=2,通過異或這種特殊的運算性質,用它來做對稱加密是比較好的選擇。
下面給一個JAVA的簡單實現:
將1234用密鑰abc加密。
思路:
1、先將1234轉換成二進制,即ASCII碼。

加密:
1、2、3、4分別對應着49、50、51、52
49 -> 加密過程為:49 ^ 密鑰 ^ 鹽值 -> m1
50 -> 加密過程為:50 ^ 密鑰 ^ m1 -> m2
51 -> 加密過程為:51 ^ 密鑰 ^ m2 -> m3
52 -> 加密過程為:52 ^ 密鑰 ^ m3 -> m4
經過上述運算后,密文就變成了m1、m2、m3、m4。
解密:
解密是上面加密的逆運算:已知條件為m1、m2、m3、m4
m4 -> 解密過程為:m4 ^ m3 ^ 密鑰 -> 52
m3 -> 解密過程為:m3^ m2 ^ 密鑰 -> 51
m2 -> 解密過程為:m2 ^ m1 ^ 密鑰 -> 50
m1 -> 解密過程為:m1 ^ 鹽值 ^ 密鑰 -> 49
下面給出JAVA實現代碼:
package com.lee;
public class Encryption {
public static void main(String[] args) {
String content = "1234"; //需要加密的字符
String key = "abc"; //密鑰
byte[] result = encryption(content, key);
System.out.println("1234加密后的值:" + new String(result));
System.out.println("---------------");
System.out.println("1234解密后的值:" +new String(decipher(new String(result), key)));
}
public static byte[] encryption(String content,String key){
byte[] contentBytes = content.getBytes();
byte[] keyBytes = key.getBytes();
byte dkey = 0;
for(byte b : keyBytes){
dkey ^= b;
}
byte salt = 0; //隨機鹽值
byte[] result = new byte[contentBytes.length];
for(int i = 0 ; i < contentBytes.length; i++){
salt = (byte)(contentBytes[i] ^ dkey ^ salt);
result[i] = salt;
}
return result;
}
public static byte[] decipher(String content,String key){
byte[] contentBytes = content.getBytes();
byte[] keyBytes = key.getBytes();
byte dkey = 0;
for(byte b : keyBytes){
dkey ^= b;
}
byte salt = 0; //隨機鹽值
byte[] result = new byte[contentBytes.length];
for(int i = contentBytes.length - 1 ; i >= 0 ; i--){
if(i == 0){
salt = 0;
}else{
salt = contentBytes[i - 1];
}
result[i] = (byte)(contentBytes[i] ^ dkey ^ salt);
}
return result;
}
}
輸出結果為:

