XOR 異或加密簡介
XOR 加密簡介
本文介紹一種簡單高效、非常安全的加密方法:XOR 加密。
一、 XOR 運算
邏輯運算之中,除了
AND
和
OR
,還有一種
XOR
運算,中文稱為"異或運算"。
它的定義是:兩個值相同時,返回false
,否則返回true
。也就是說,XOR
可以用來判斷兩個值是否不同。
true XOR true // false false XOR false // false true XOR false // true true XOR false // true
JavaScript 語言的二進位制運算,有一個專門的 XOR 運算子,寫作^
。
1 ^ 1 // 0 0 ^ 0 // 0 1 ^
0 // 1 0 ^ 1 // 1
上面程式碼中,如果兩個二進位制位相同,就返回0
,表示false
;否則返回1
,表示true
。
二、 XOR 的應用
XOR 運算有一個很奇妙的特點:如果對一個值連續做兩次 XOR,會返回這個值本身。
// 第一次 XOR 1010 ^ 1111 // 0101 // 第二次 XOR 0101 ^ 1111 // 1010
上面程式碼中,原始值是1010
,再任意選擇一個值(上例是1111
),做兩次 XOR,最後總是會得到原始值1010
。這在數學上是很容易證明的。
三、加密應用
XOR 的這個特點,使得它可以用於資訊的加密。
message XOR key // cipherText cipherText XOR key // message
上面程式碼中,原始資訊是message
,金鑰是key
,第一次 XOR 會得到加密文字cipherText
。對方拿到以後,再用key
做一次 XOR 運算,就會還原得到message
。
四、完美保密性
二戰期間,各國為了電報加密,對密碼學進行了大量的研究和實踐,其中就包括 XOR 加密。
戰後,美國數學家夏農(Claude Shannon)將他的研究成果公開發表,證明了只要滿足兩個條件,XOR 加密是無法破解的。
key
的長度大於等於message
key
必須是一次性的,且每次都要隨機產生
理由很簡單,如果每次的key
都是隨機的,那麼產生的CipherText
具有所有可能的值,而且是均勻分佈,無法從CipherText
message
的任何特徵。也就是說,它具有最大的"資訊熵",因此完全不可能破解。這被稱為 XOR 的"完美保密性"(perfect
secrecy)。
滿足上面兩個條件的key
,叫做
one-time pad(縮寫為OTP),意思是"一次性密碼本",因為以前這樣的key
都是印刷成密碼本,每次使用的時候,必須從其中挑選key
。
五、例項:雜湊加密
下面的例子使用 XOR,對使用者的登陸密碼進行加密。實際執行效果看這裡。
第一步,使用者設定登陸密碼的時候,算出這個密碼的雜湊,這裡使用的是 MD5 演算法,也可以採用其他雜湊演算法。
const message = md5(password);
第二步,生成一個隨機的 key。
// 生成一個隨機整數,範圍是 [min, max] function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // 生成一個隨機的十六進位制的值,在 0 ~ f 之間 function getHex() { let n = 0; for (let i = 4; i > 0; i--) { n = (getRandomInt(0, 1) << (i - 1)) + n; } return n.toString(16); } // 生成一個32位的十六進位制值,用作一次性 Key function getOTP() { const arr = []; for (let i = 0; i < 32; i++) { arr.push(getHex()); } return arr.join(''); }
上面程式碼中,生成的key
是32位的十六進位制值,對應 MD5 產生的128位的二進位制雜湊。
第三步,進行 XOR 運算,求出加密後的message
。
function getXOR(message, key) { const arr = []; for (let i = 0; i < 32; i++) { const m = parseInt(message.substr(i, 1), 16); const k = parseInt(key.substr(i, 1), 16); arr.push((m ^ k).toString(16)); } return arr.join(''); }
使用這種方法儲存使用者的登陸密碼,即使加密文字洩露,只要一次性的金鑰(key
)沒有洩露,對方也無法破解。
(完)