釋出
2011 年 3 月 13 日 (上次更新:2011 年 3 月 13 日)

簡單 XOR 加密

評分:3.9/5 (210 票)
*****
好了,入門級的加密課程

計算機上的所有內容都儲存為二進位制資料,形式為位元組(8 位,或單個 1 或 0)

二進位制資料可以使用基於一種稱為異或 (xor) 或 exclusive or 的布林運算的“金鑰”輕鬆“加密”。
當我們用另一個位來異或一個單一位(1 或 0)時

如果 1 位為真,而 1 位為假,則返回真,否則返回假;
所以

1 異或 1 = 0
1 異或 0 = 1
0 異或 1 = 1
0 異或 0 = 0

現在,這種方法有用的一個原因是,如果我們取新位並使用相同的金鑰(第二位)對其進行異或,結果將始終是第一位。
所以

1 異或 1 異或 1 = 1;
1 異或 0 異或 0 = 1;


當然,在單個位上它不會有太大作用,但是當您進入更高的記憶體級別時,這是一種相當簡單且(有時)有效的(參見文章後面)加密方法。

現在,當我說所有內容都儲存為二進位制資料時,這也意味著字串,單個 char 儲存為 ascii 或 unicode(或其他一些協議,但我只見過這兩個)值。

例如

字母 'h' 在 ascii 中 = 104
字母 'i' 在 ascii 中 = 105

將整數轉換為二進位制數有點困難,但可以做到。
當您檢視二進位制數時,您可以反向讀取它並新增每一位的值,如下所示

2x 25 24 23 22 21 20
所以二進位制數
01110011

1
2
0    1    1    1   0   0   1   1 
0 + 64 + 32 + 16 + 0 + 0 + 2 + 1


是 115 或 's'

現在一切都很好,您可以給您的朋友傳送小紙條,沒有人能看懂您在說什麼,但當然您也可以直接寫二進位制的東西,它會執行相同的操作 =)

在 c++ 中,^ 運算子是異或運算子。
如果我有一個我想加密的字串,我可以這樣做

1
2
3
4
5
6
7
8
9
10
 string toEncrypt = "fail";
 char keyToEncrypt = 's'; //remember 115 in ascii

 for (int temp = 0; temp < toEncrypt.size(); temp++)
   toEncrypt[temp] ^= keyToEncrypt;
 cout << "nThe encrypted data = " << toEncrypt;

 for (int temp = 0; temp < toEncrypt.size(); temp++)
   toEncrypt[temp] ^= keyToEncrypt; //notice we're using the exact same key, to unencrypt the data.
 cout << "nThe unencrypted data = " << toEncrypt;


當然,這一切都很好,但是對於任何為其資料使用簡單金鑰的人來說,這裡有一個練習,如果有人可以訪問您的程式。並且他們可以加密他們自己的一些資料,並且可以訪問該加密的輸出,他們可以得到您的金鑰。示例

1
2
3
4
5
6
7
8
9
10
 char original = "f";
 char key = "s";
 char end;
 char getKey;

 end = original ^ key;

 // now here's the kicker

 getKey = original ^ end;


因此,您必須變得狡猾,一種更安全地加密和解密資料的 reeeeeaaaaly 簡單的方法可能是這樣的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 string original = "super flying monkeys are aweseome, aren't they?";
 cout << "Original data = " << original;
 string encrypted = "";
 string unencrypt = "";
 char key = 'x';

 for (int temp = 0; temp < original.size(); temp++){
  encrypted += original[temp] ^ (int(key) + temp) % 255;
 }
 cout << "nEncrypted data = " << encrypted;

 for (int temp = 0; temp < original.size(); temp++){
  unencrypted += encrypted[temp] ^ (int(key) + temp) % 255;
 }
 cout << "nUnencrypted data = " << unencrypt;


當然,您應該做一些簡單的遞增之外的事情,因為這很容易被嗅探到。

但是你明白了,一個簡單的加密課程!