字元串的Base64編碼
我到處讀到,唯一的二進制/十六進制值的 base64 編碼會產生唯一的輸出。以下兩個字元串編碼為幾乎相同的輸出。
{"alg":"SHA1","typ":"JWT","iat": "Sep 8 2018 8:51AM", "exp": "Sep 8 2018 9:11AM"}
給出輸出:
eyJhbGciOiJTSEExIiwidHlwIjoiSldUIiwiaWF0IjogIlNlcCAgOCAyMDE4ICA4OjUxQU0iLCAiZXhwIjogIlNlcCAgOCAyMDE4ICA5OjExQU0ifQ==
儘管
{"alg":"SHA1","typ":"JWT","iat": "Sep 8 2018 9:10AM", "exp": "Sep 8 2018 9:30AM"}
給出輸出:
eyJhbGciOiJTSEExIiwidHlwIjoiSldUIiwiaWF0IjogIlNlcCAgOCAyMDE4ICA5OjEwQU0iLCAiZXhwIjogIlNlcCAgOCAyMDE4ICA5OjMwQU0ifQ==
兩者的唯一區別是:
ExQU0ifQ==
和MwQU0ifQ==
在輸出的末尾。只有兩個字元串的時間不同;這就是差異如此微小的原因嗎?
base64 編碼的全部目的是獲取任意字節值並將它們轉換為有限的 ASCII 字元子集,以便它們可以“安全”發送(舊的傳輸協議可能會混淆某些字節值,因為例如某些原始字節對那些具有特殊含義協議;預計不會更改的唯一數據是純 ASCII 文本。)
它通過將三個字節(24 位)編碼為 4 個字元(每個字元有 64 個值,因此將 6 位編碼為 $ 2^6 =64 $ )以非常簡單的方式(不完整組的一些額外規則)。因此,兩條消息中每個對齊的相同三個字節每次都會被編碼為相同的 4 個字元。因此,僅更改 1 個字節最多會更改結果中的 2 個相鄰字元,如果您研究轉換,這是顯而易見的。
沒有更多變化的期望:它只是相同順序的相同位的另一種表示,並且在接收端很容易反轉。
事實上(IMO)在任何合理的協議中,您的 JSON 格式的數據都應該按原樣發送,因為它已經全部是 ASCII,而 base64 編碼除了使用更多頻寬之外什麼也沒增加。加密後,它應該是類似隨機的二進制數據,並且可以以 base64 格式發送(這實際上是習慣性的:PEM 和 PGP 發送他們的消息 base64 編碼,並且通常也發送二進制郵件附件。)
既然只有兩個字元串的時間不同,那為什麼差異如此之小?
Base64 無意在密碼學上安全,因此如果輸入的微小變化導致輸出的微小變化是完全可以接受的。在這種特殊情況下,您會得到以下子字元串的差異
ExQU0ifQ== vs MwQU0ifQ==
和
E4ICA5OjEwQU vs E4ICA4OjUxQU
總共有 5 個不同的字元,這是預期的下限,因為輸入的 5 個字節已更改。您可能還需要注意,Base64 基本上一次佔用 3 個字節,並將它們編碼為 4 個 Base64 字元,獨立於所有其他字節,因此沒有預期的傳播。