解密 Base64 編碼的單字母密碼
我正在嘗試解密已使用單字母密碼加密的密文正文。我遇到的問題是明文在加密之前是 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 是E
base64 字母表中的索引。我不確定這是否重要,但它們鍵數組中的所有索引我沒有映射(一些不太常見的字母,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?????
其中 bits
ABC
和DEF
(GHI
對應於每個明文字節的最高三位)可以是:
000
僅當字節代表一個控製字元(其中唯一可能出現在純 ASCII 文本中的是換行符 =00001010
,輸入 =00001101
,通常後面總是跟一個換行符,可能還有製表符 =00001001
);001
對於空格 (00100000
)、數字(下一位總是1
)和大多數標點符號;010
對於大寫字母(以及字元、@
、[
、\
和]
);或者^``_
011
用於小寫字母(以及字元、```、{
和|
)。}``~
請注意,在純 ASCII 文本中,每個 8 位字節(即 bits 及以上)的
A
最高D
位G
始終為0
。(也就是說,1
如果您的明文實際上是用某種“擴展的 ASCII ”編碼(如 ISO Latin 1)編寫的,或者可能是 UTF-8 編碼中的 Unicode,並且包含一些非 ASCII 字元,則可能是這樣。)例如,假設您猜測明文中最常見的字節可能是 ASCII 空間(二進制),因此每個 4 字元組末尾
00100000
最常見的 base64 字元(我們隨意說它X
)可能編碼位。100000
這意味著這個 base64 字元
X
基本上不應該作為 4 字元組的第一個字元出現(因為這會使 bitA
above1
),並且應該很少出現作為第二個字元(因為這會使 bitsDEF
be000
,這應該很漂亮除非明文充滿換行符,否則很少見)。如果確實如此,那麼您可以確信自己猜對了。此外,然後您可以查看
X
密文中前面的 base64 字元,並非常確定它們都代表以結尾的六位 base64 程式碼00
(因為無論如何 bit都G
必須0
在 ASCII 文本中,如果 bitH
是1
,那將解碼到相當不常見的明文字節01100000
= ```),它(連同它們在四個不同位置的頻率)應該有助於縮小它們的可能值。類似地,你可以猜到四字元組的第一個位置中最常見的 base64 字元可能對 bits 進行編碼
001000
,而在它後面的第二個位置中最常見的兩個字元可能編碼000100
and000101
(假設一個空格最常見後跟一個小寫字母;當然,位序列000110
和000111
也可能相當常見,因為它們來自一個空格,後跟一個大寫字母)。第三個位置最常見的 base64 字元最有可能代表位
000001
(即空格後跟一個字母),特別是如果它通常不在最常見的第四組字元(即X
上面)之前,因為這會再次產生涉及反引號字元的不太可能的明文序列```=01100000
.*此外,假設您的明文確實是英文 ASCII 文本,您可以開始使用的另一種方法是在密文中查找 base64 字元的常見重複序列,並假設它們可能對應於英文文本中的常見字元序列。
例如,英文 ASCII 文本中最常見的五字節序列可能是
the
(即“the”兩邊被空格包圍)。當分成三字節組進行 base64 編碼時,根據組邊界恰好落在哪裡,您可以得到以下任一結果:
th
和e ?
;? t
和he
; 或者??
,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
您可能想要查找的其他一些英文文本中相當常見的字節序列包括
a
和I
(即“a”和“I”被空格包圍),如果您已經確定了哪些 base64 字元,這兩者都可以很容易辨識對應於組的開頭和結尾的空格,以及and
(另一個相當常見的由空格包圍的三字母單詞,以與the
上述類似的模式出現,但通常不太常見以至於相當容易區分)和四個-字節序列to
,of
,in
,at
等。不過,在您設法解碼至少一些常見字母之前,您可能希望基本上忽略後者,因為英語中有相當多常見的兩個字母單詞,並且它們的相對頻率可能會有所不同關於寫作的主題和風格。)也就是說,一切總是取決於明文實際上是什麼。例如,這個答案的Markdown原始碼充滿*了反引號,通常跟在或後面跟一個空格,因為那是
inline code
.