h5前端必需了解的異或加密解密

在當(dāng)前h5各種活動漫天轟炸的時(shí)代,大量的訪問量給h5帶來了機(jī)遇,同時(shí)也帶來了一些安全隱患,如何能對數(shù)據(jù)進(jìn)行一些合理的加密成了我們H5必須考慮的問題,今天就先寫下異或

一、 XOR 運(yùn)算

邏輯運(yùn)算之中,除了 ANDOR,還有一種 XOR 運(yùn)算,中文稱為"異或運(yùn)算"。

它的定義是:兩個(gè)值相同時(shí),返回false,否則返回true。也就是說,XOR可以用來判斷兩個(gè)值是否不同。


true XOR true // false
false XOR false // false
true XOR false // true
true XOR false // true

image

JavaScript 語言的二進(jìn)制運(yùn)算,有一個(gè)專門的 XOR 運(yùn)算符,寫作^。


1 ^ 1 // 0
0 ^ 0 // 0
1 ^ 0 // 1
0 ^ 1 // 1

上面代碼中,如果兩個(gè)二進(jìn)制位相同,就返回0,表示false;否則返回1,表示true。

二、 XOR 的應(yīng)用

XOR 運(yùn)算有一個(gè)很奇妙的特點(diǎn):如果對一個(gè)值連續(xù)做兩次 XOR,會返回這個(gè)值本身。


// 第一次 XOR
1010 ^ 1111 // 0101

// 第二次 XOR
0101 ^ 1111 // 1010

上面代碼中,原始值是1010,再任意選擇一個(gè)值(上例是1111),做兩次 XOR,最后總是會得到原始值1010。這在數(shù)學(xué)上是很容易證明的。

三、加密應(yīng)用

XOR 的這個(gè)特點(diǎn),使得它可以用于信息的加密。


message XOR key // cipherText
cipherText XOR key // message

上面代碼中,原始信息是message,密鑰是key,第一次 XOR 會得到加密文本cipherText。對方拿到以后,再用key做一次 XOR 運(yùn)算,就會還原得到message。

image

四、完美保密性

二戰(zhàn)期間,各國為了電報(bào)加密,對密碼學(xué)進(jìn)行了大量的研究和實(shí)踐,其中就包括 XOR 加密。

image

戰(zhàn)后,美國數(shù)學(xué)家香農(nóng)(Claude Shannon)將他的研究成果公開發(fā)表,證明了只要滿足兩個(gè)條件,XOR 加密是無法破解的。

  • key的長度大于等于message
  • key必須是一次性的,且每次都要隨機(jī)產(chǎn)生

理由很簡單,如果每次的key都是隨機(jī)的,那么產(chǎn)生的CipherText具有所有可能的值,而且是均勻分布,無法從CipherText看出message的任何特征。也就是說,它具有最大的"信息熵",因此完全不可能破解。這被稱為 XOR 的"完美保密性"(perfect secrecy)。

滿足上面兩個(gè)條件的key,叫做 one-time pad(縮寫為OTP),意思是"一次性密碼本",因?yàn)橐郧斑@樣的key都是印刷成密碼本,每次使用的時(shí)候,必須從其中挑選key

五、實(shí)例:哈希加密

下面的例子使用 XOR,對用戶的登陸密碼進(jìn)行加密。實(shí)際運(yùn)行效果看這里

第一步,用戶設(shè)置登陸密碼的時(shí)候,算出這個(gè)密碼的哈希,這里使用的是 MD5 算法,也可以采用其他哈希算法。


const message = md5(password);

第二步,生成一個(gè)隨機(jī)的 key。


// 生成一個(gè)隨機(jī)整數(shù),范圍是 [min, max]
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 生成一個(gè)隨機(jī)的十六進(jìn)制的值,在 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);
}

// 生成一個(gè)32位的十六進(jìn)制值,用作一次性 Key
function getOTP() {
  const arr = [];
  for (let i = 0; i < 32; i++) {
    arr.push(getHex());
  }
  return arr.join('');
}

上面代碼中,生成的key是32位的十六進(jìn)制值,對應(yīng) MD5 產(chǎn)生的128位的二進(jìn)制哈希。

第三步,進(jìn)行 XOR 運(yùn)算,求出加密后的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)沒有泄露,對方也無法破解。

  典型XOR解密及unicode轉(zhuǎn)義漢字
  // 異或解密(異或加密相當(dāng)于一個(gè)雙重加密,雙重保障更安全)
export function Restore(str, keyIndex)
  {
    var crytxt = '';
    var k, keylen = keyIndex.length;
    for(var i=0; i<str.length; i++) {
      k = i % keylen;
      crytxt += String.fromCharCode(str.charCodeAt(i) ^ keyIndex.charCodeAt(k));
    }
    return toChineseWords(crytxt);

}

export function toChineseWords(data){
  var str= unescape(data.replace(/\\/g, "%"));
  str= JSON.parse(str); 
  return  str
}

文章資料:http://www.ruanyifeng.com/blog/2017/05/xor.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,666評論 1 32
  • 我三十六歲了,歲月的年輪就如此順其自然的增多,對于今年又多了一個(gè)說法,“本命年生日”!本命年,經(jīng)歷過兩次卻從...
    毋小新閱讀 414評論 2 2
  • 此年此景閱讀 443評論 0 1
  • 又是一個(gè)月圓之夜。 冬天的晚上,月光清冷清冷的,灑在無邊的天幕上。星星怕是被這清冷凍的不輕,一個(gè)個(gè)都躲在幕后不敢出...
    芊小蔚閱讀 230評論 0 0
  • 今天徐薇很忙,我們也就哪也沒去,在家看看電視,玩玩游戲,這兩天也就啥都沒做了,讀經(jīng)也休息了,等回去再開始吧...
    泉州煒圣媽閱讀 186評論 0 0

友情鏈接更多精彩內(nèi)容