Symmetric

解密 Base64 編碼的單字母密碼

  • September 17, 2018

我正在嘗試解密已使用單字母密碼加密的密文正文。我遇到的問題是明文在加密之前是 base64 編碼的。在這個謎題中,加密方案使用一個包含 0-63 排列的數組作為密鑰。它獲取明文並通過在 base64 字母表中獲取其索引並將其用作密鑰中的索引來加密每個字元。然後將該鍵值用作索引,以從 64 位字母表中獲取密文字元。

我了解解決此類密碼的典型方法是通過字母的頻率分析(知道 e 是最常見的字母等等)。我的困惑來自如何做到這一點,因為明文是 base64 編碼的。

我已經閱讀了這篇文章,但無法理解如何實際應用它。我已經能夠編寫一些 python 來計算密文中每 4 個字元的頻率,但我不確定下一步是獲取明文/密鑰。

我嘗試的其中一件事是將頻率分析的結果映射回明文。例如e二進制產量01100101。然後,如果您有一個e作為明文中的第3個字元,那麼 base64 編碼的明文的第 4個字元將是l(100101)。從那裡我會查看對密文的分析,並看到最常見的字母是映射到的V含義。然後計算我得到的字母在base 64字母表中的索引差異 V``l

$$ 64 - 37 = 27 $$ (37 = 的索引l,到達字母表的末尾) $$ 27 + 21 = 48 $$ (加上 21 的索引V)。這給我留下了 $ key[30] = 48 $ e, 30 是base64 字母表中的索引。我對多個字母重複了此操作,但在嘗試使用該密鑰解密然後對返回的文本進行解編碼時,它沒有產生任何可讀的文本。 此外,我嘗試將大寫和小寫字母映射到相同的結果,因為我相信這只會產生不區分大小寫的明文。繼續上面的例子,我還要設置 $ key[4] = 48 $ 同樣,4 是Ebase64 字母表中的索引。

我不確定這是否重要,但它們鍵數組中的所有索引我沒有映射(一些不太常見的字母,0-9,和’+’’/‘我初始化為0。

任何關於從這裡去哪里或如何解決這個問題的提示將不勝感激。

在您弄清楚至少兩個相鄰的 base64 位置(1 和 2、2 和 3 或 3 和 4)中最常見字元的解密之前,您可能不會得到任何(甚至部分)可讀的文本。

這是因為每個明文字節的八位在編碼過程中分散在兩個相鄰的六位 base64 字元中。因此,即使您設法正確解密了這兩個字元之一,您仍然最多只能恢復八位中的六個。這至少留下了兩位您只需要猜測其值的位。

也就是說,猜測這兩個失去位的難度很大程度上取決於哪些位恰好失去了。特別是,所有字母(- ,- )的ASCII 程式碼都將八位中的最高兩位設置為。(第三高位是字母是大寫還是小寫。)因此,如果您的純文字實際上是 ASCII 文本,您可以通過嘗試解密每個中的最後一個 base64 字元來獲得一些部分可讀的輸出四人組,並假設前一個字元解碼為以 bits 結尾的內容。A``Z``a``z``01``0``1``01

(但是,請注意,常見的明文字節,如果您的明文確實是 ASCII 文本,很可能根本不是字母,而是空格字元,其 ASCII 碼 32 =00100000在二進制中以 開頭00,而不是01。同樣如此數字、換行符和大多數但不是全部的標點符號。)


更一般地說,您可能想要利用 ASCII 碼的結構,這使得每個明文字節的最高兩位或三位非常可預測。特別是,如果您將任意三個 8 位純文字字節組(代表三個 ASCII 字元)分成四組,每組 6 位(就像 base64 編碼一樣),您最終會得到如下結果:

ABC??? ??DEF? ????GH I?????

其中 bitsABCDEFGHI對應於每個明文字節的最高三位)可以是:

  • 000 當字節代表一個控製字元(其中唯一可能出現在純 ASCII 文本中的是換行符 = 00001010,輸入 = 00001101,通常後面總是跟一個換行符,可能還有製表符 = 00001001);
  • 001對於空格 ( 00100000)、數字(下一位總是1)和大多數標點符號;
  • 010對於大寫字母(以及字元、@[\]);或者^``_
  • 011用於小寫字母(以及字元、```、{|)。}``~

請注意,在純 ASCII 文本中,每個 8 位字節(即 bits 及以上)的A最高DG始終 0。(也就是說,1如果您的明文實際上是用某種“擴展的 ASCII ”編碼(如 ISO Latin 1)編寫的,或者可能是 UTF-8 編碼中的 Unicode,並且包含一些非 ASCII 字元,則可能是這樣。)


例如,假設您猜測明文中最常見的字節可能是 ASCII 空間(二進制),因此每個 4 字元組末尾00100000最常見的 base64 字元(我們隨意說它X)可能編碼位。100000

這意味著這個 base64 字元X基本上應該作為 4 字元組的第一個字元出現(因為這會使 bit Aabove 1),並且應該很少出現作為第二個字元(因為這會使 bits DEFbe 000,這應該很漂亮除非明文充滿換行符,否則很少見)。如果確實如此,那麼您可以確信自己猜對了。

此外,然後您可以查看X密文中前面的 base64 字元,並非常確定它們都代表以結尾的六位 base64 程式碼00(因為無論如何 bit都G必須0在 ASCII 文本中,如果 bitH1,那將解碼到相當不常見的明文字節01100000= ```),它(連同它們在四個不同位置的頻率)應該有助於縮小它們的可能值。

類似地,你可以猜到四字元組的第一個位置中最常見的 base64 字元可能對 bits 進行編碼001000,而在它後面的第二個位置中最常見的兩個字元可能編碼000100and 000101(假設一個空格最常見後跟一個小寫字母;當然,位序列000110000111也可能相當常見,因為它們來自一個空格,後跟一個大寫字母)。

第三個位置最常見的 base64 字元最有可能代表位000001(即空格後跟一個字母),特別是如果它通常不在最常見的第四組字元(即X上面)之前,因為這會再次產生涉及反引號字元的不太可能的明文序列```= 01100000.*


此外,假設您的明文確實是英文 ASCII 文本,您可以開始使用的另一種方法是在密文中查找 base64 字元的常見重複序列,並假設它們可能對應於英文文本中的常見字元序列。

例如,英文 ASCII 文本中最常見的五字節序列可能是the(即“the”兩邊被空格包圍)。當分成三字節組進行 base64 編碼時,根據組邊界恰好落在哪裡,您可以得到以下任一結果:

  • the ?;
  • ? the; 或者
  • ??,the??,

where?代表一些可變字節(很可能是一個字母)。因此,4 個字元的 base64 組編碼th,the並且he應該都非常常見,並且出現的頻率大致相同(儘管請注意,頻率不僅可以隨機出現偏差,而且還可以通過其他常見英語單詞的存在相同的開頭或結尾,例如“that”、“this”、“those”、“these”、“they”、“there”和“then”,以及“he”和“she”,當然還有大寫形式“The”)。

此外,您可以通過查看周圍加密的 base64 字元來區分編碼這些不同 3 字節序列的 base64 組。例如,編碼組的the前面應該經常是編碼 ASCII 空間的最低六位的 base64 字元(即100000),然後是編碼 ASCII 空間的最高六位的 base64 字元(即001000)。此外,由於它們對通常常見的空格進行編碼,因此這兩個 base64 字元通常應該是 4 字元組的該位置中最常見的字元。

(當然,該組the並不總是在空格之前或之後,因為它也可以作為較長單詞的一部分出現,或者可能出現在一行的開頭或結尾。但是最常見的明文字節之前和之後應該仍然是空格。)

類似地,四字元組編碼th應該以編碼 ASCII 空間的前六位的 base64 字元開頭(因此在組的第一個位置相當常見),並且通常應該跟隨一個特定的三個序列編碼e後跟一個字母的 base64 字元。並且,相應地,編碼的組he應該以對空格的最後六位進行編碼的公共字元結尾,並且通常應該在與前一組末尾對應的兩個base64 字元之前。t

您可能想要查找的其他一些英文文本中相當常見的字節序列包括aI(即“a”和“I”被空格包圍),如果您已經確定了哪些 base64 字元,這兩者都可以很容易辨識對應於組的開頭和結尾的空格,以及and(另一個相當常見的由空格包圍的三字母單詞,以與the上述類似的模式出現,但通常不太常見以至於相當容易區分)和四個-字節序列to, of, in,at等。不過,在您設法解碼至少一些常見字母之前,您可能希望基本上忽略後者,因為英語中有相當多常見的兩個字母單詞,並且它們的相對頻率可能會有所不同關於寫作的主題和風格。


)也就是說,一切總是取決於明文實際上是什麼。例如,這個答案的Markdown原始碼充滿*了反引號,通常跟在或後面跟一個空格,因為那是inline code.

引用自:https://crypto.stackexchange.com/questions/62425