0


密码分析学-Enigma机破解

密码分析学

Enigma机破解

目录

作业要求

(1)给定明文HELLOWORLD,按照以下给定参数,编程实现Enigma机的加密,并输出对应的密文。

  • 接线板(6条连线)K1:S = [1, 0, 2, 4, 3, 5, 13, 7, 8, 9, 24, 11, 20, 6, 14, 15, 16, 17, 22, 19, 12, 21, 18, 23, 10, 25]即a与b相连,d与e相连,g与n相连,k与y相连,m与u相连,s与w相连
  • 扰频器组合(固定3个转子,无需从5个中选择3个)快速转子QUICK = [0, 18, 24, 10, 12, 20, 8, 6, 14, 2, 11, 15, 22, 3, 25, 7, 17, 13, 1, 5, 23, 9, 16, 21, 19, 4]即快速转子的表格中左侧一列为0,1,2,…,25,右侧一列0,18,24,…,4;下同中速转子MID = [0, 10, 4, 2, 8, 1, 18, 20, 22, 19, 13, 6, 17, 5, 9, 3, 24, 14, 12, 25, 21, 11, 7, 16, 15, 23]慢速转子SLOW = [24, 22, 7, 10, 12, 19, 23, 0, 14, 6, 9, 15, 8, 25, 20, 17, 3, 1, 18, 4, 21, 5, 11, 13, 16, 2]各转子起始点K2:(4, 4, 16)
  • 反射器T = [10, 20, 14, 8, 25, 15, 16, 21, 3, 18, 0, 23, 13, 12, 2, 5, 6, 19, 9, 17, 1, 7, 24, 11, 22, 4]即a与k相连,b与u相连,……

(2)给定如下明密文数据流,1)中的快中慢三个转子和反射器的定义不变,尝试恢复密钥K1和K2。

​ 明文:…HELLOWORLD…

​ 密文:…WELLDONEEFGHIJ…

摘要

加密结果:

     E
    
    
     n
    
    
     
      c
     
     
      
       K
      
      
       1
      
      
       ,
      
      
       K
      
      
       2
      
     
    
    
     (
    
    
     "
    
    
     H
    
    
     E
    
    
     L
    
    
     L
    
    
     O
    
    
     W
    
    
     O
    
    
     R
    
    
     L
    
    
     D
    
    
     "
    
    
     )
    
    
     =
    
    
     "
    
    
     M
    
    
     U
    
    
     C
    
    
     D
    
    
     U
    
    
     G
    
    
     W
    
    
     P
    
    
     X
    
    
     B
    
    
     "
    
   
   
     Enc_{K1,K2}("HELLOWORLD") ="MUCDUGWPXB" 
   
  
 EncK1,K2​("HELLOWORLD")="MUCDUGWPXB"

破解结果:

不考虑未知的字母,未知的字母全部当做没有接线,一共有38个解。python运行时间:8.356976747512817s

格式:[K2, K1]

[[2,14,8],  [0,1,2,13,25,18,19,20,17,9,11,10,12,3,14,15,16,8,5,6,7,21,24,23,22,4]] 
[[2,14,8],  [0,1,2,13,25,23,19,20,8,9,11,10,17,3,14,15,16,12,18,6,7,21,24,5,22,4]] 
[[2,14,8],  [0,1,5,13,25,2,19,20,8,9,11,10,12,3,14,15,16,17,18,6,7,21,24,23,22,4]] 
[[2,14,8],  [0,1,2,13,25,8,19,20,5,9,11,10,12,3,14,15,16,18,17,6,7,21,24,23,22,4]] 
[[2,14,8],  [0,1,2,13,25,12,19,20,8,9,11,10,5,3,14,15,16,23,18,6,7,21,24,17,22,4]] 

此处省略部分,太长了..

[[24,17,3], [0,1,2,3,4,20,24,12,8,17,10,21,7,18,19,22,16,9,13,14,5,11,15,23,6,25]]
[[24,17,3], [0,1,2,3,4,9,24,12,8,5,10,21,7,18,19,22,16,20,13,14,17,11,15,23,6,25]]
[[24,17,3], [5,1,2,3,4,0,24,12,8,9,10,21,7,18,19,22,16,23,13,14,20,11,15,17,6,25]]
[[25,10,6], [0,4,3,2,1,13,8,23,6,9,22,19,12,5,24,15,16,18,17,11,20,21,10,7,14,25]]

正文

一:Enigma机加密

1.1 背景

​   Enigma密码机在1920年代早期开始被用于商业,也被一些国家的军队与政府采用过,在这些国家中,最著名的是第二次世界大战时的纳粹德国。Enigma密码机的大部分设置都会在一段时间(一般为一天)以后被更换。1932年,波兰密码学家马里安·雷耶夫斯基,杰尔兹·罗佐基和亨里克·佐加尔斯基破译了德军的Enigma机,但随后德军对Enigma机进行了改进。波兰战败后,将研究成果分享给英法,随后英国的图灵和其他专家共同破译了Enigma机。

1.2 加密原理

  • Enigma密码机的构造共由五个主要部件组成。分别是:
  1. 包含26个英文字母的键盘: 输入端,每次输入一个英文字母。
  2. 线路接线板: 将l对字母相连接,进行加密工作。
  3. 扰频组合: 由快速扰频器、中速扰频器、慢速扰频器组成,进行加密工作。
  4. 反射器: 保证加密后得到的字母与输入的字母一定不相同。
  5. 包含26个英文字母的显示灯的显示灯板: 输出端,在键盘上输入一个英文字母后,灯盘上都会有一个英文字母亮起来,代表明文字母加密后的所对应的密文字母。
  • Enigma密码机的加密原理 ​    Enigma密码机加密是一种多表代换的对称加密算法,逐字母加密。除此之外,Enigma密码机是对称加密,加解密过程一致,不论加密还是解密,明文空间: P ∈ { A } n P\in \mathbb{{A}^n} P∈{A}n, A \mathbb{A} A表示字母表 { A − Z } {A-Z} {A−Z}密文空间: C ∈ { A } n C\in \mathbb{{A}^n} C∈{A}n秘钥: K 1 , K 2 K1,K2 K1,K2,分别表示接线板和三个转子的初始位置加解密算法:设置好 K 1 K1 K1和 K 2 K2 K2后,明文 P P P 经过:① 标有26个英文字母的线路接线板( S S S)②扰频组合( R R R)③反射器( T T T)④扰频组合( R − 1 R^{-1} R−1)⑤标有26个英文字母的线路接线板( S S S)得到密文 C C C,解密同理。因为加解密算法一致,所以此处不作区分。 C = E n c K 1 , K 2 ( P ) P = E n c K 1 , K 2 ( C ) C =Enc_{K1,K2}(P)\ P = Enc_{K1,K2}(C) C=EncK1,K2​(P)P=EncK1,K2​(C)
  • 扰频器的作用

​   扰频器也称作转子。单个转子的加密是一种单表置换。转子的左右两侧各有26个点,分别代表A-Z这26个英文字母。一端输入一端输出。为了达到加密的目的,将左右两侧的字母交叉连接,例如:转子左侧的字母A并不与转子右侧的A相连,而是与字母E相连,即表示字母A经过扰频器的加密后变成了字母E。

​   因为这种单个转子提供的密码表是固定不变的,加密出来的密文比较容易被破解,因此选择三个转子串联在一起从而达到加密的目的。
三个转子被串联后,输入的字母经过这三个转子被进行多次替换。如果转子不转,那么输入的字母不论经过几个串联的转子,最终得到的依旧是一个固定的密码表,安全性依旧不高。因此为了提高加密的安全性,每输入一个字母后,第一个转子就会自动转动一格。当第一个转子转动一圈后,第二个转子就转动一格。同理,第二个转子转动一圈后,第三个转子转动一格。这样原来的单表置换经过旋转变为多表置换,使得安全性更高。

​   根据

    K
   
   
    e
   
   
    r
   
   
    c
   
   
    k
   
   
    h
   
   
    o
   
   
    f
   
   
    f
   
   
    s
   
  
  
   Kerckhoffs
  
 
Kerckhoffs假设,加密算法的内部结构是公开的,也就是说转子的内部结构对于加解密双方来说是一致的。秘钥

 
  
   
    K
   
   
    2
   
  
  
   K2
  
 
K2 包含的是转子的排列方式和初始位置,如果有n个转子,选用m个进行加密,秘钥空间为

 
  
   
    
     ∣
    
    
     K
    
    
     2
    
    
     ∣
    
    
     =
    
    
     
      A
     
     
      n
     
     
      m
     
    
    
     ∗
    
    
     2
    
    
     
      6
     
     
      3
     
    
   
   
     |K2| = A_n^m*26^3 
   
  
 ∣K2∣=Anm​∗263

​   对于只有三个转子的Enigma机,密钥空间只有

    3
   
   
    !
   
   
    ∗
   
   
    2
   
   
    
     6
    
    
     3
    
   
   
    =
   
   
    105456
   
  
  
   3!*26^3=105456
  
 
3!∗263=105456,这种级别的安全性是不够的,这时候接线板

 
  
   
    K
   
   
    1
   
  
  
   K1
  
 
K1就起了关键作用。我们会在安全性分析中做解释。
  • ​​反射器作用

​   反射器的加密是一种固定的单表置换(这里的单表置换是自定义的,无密钥)。加密方式是将最后一个转子的其中两个触点连接起来,并将电流沿一个不同的路倒回到线路接线板。这样的反射器导致加密后的字母与输入字母一定不相同,并且使得Enigma密码机的加密过程是自反的,这也是加解密一致的关键部件。同时还让Enigma机有了另一个性质,即:一个字母不会加密成自身。这也是后面破解的关键。

在这里插入图片描述

1.3 安全性分析

​    我们说过,Enigma机的本质是一种多表替换,我们之前学习过的凯撒密码和维吉尼亚密码也是替换密码,但后两种密码我们知道会有字母频率的漏洞。主要因为他们的加密都是使用的同一张密码表,而Enigma机每加密一个字母,就会转动一下,相当于换了一张密码表,基本可以做到加密一个字母就更换一次密码表并且不重复。

​   没有了字母频率攻击的“后顾之忧”,那我们再考虑暴力破解:

​   我们在前面讨论过对于3个转子的Enigma机,他的转子排列和初始位置的组合

    K
   
   
    2
   
  
  
   K2
  
 
K2只有105456大小。这显然不够,我们来考虑接线板(

 
  
   
    K
   
   
    1
   
  
  
   K1
  
 
K1)的作用。26个字母,有 

 
  
   
    t
   
  
  
   t
  
 
t 根连线,那么就有

 
  
   
    
     
      
       26
      
      
       !
      
     
     
      
       (
      
      
       26
      
      
       −
      
      
       t
      
      
       )
      
      
       !
      
      
       ∗
      
      
       t
      
      
       !
      
      
       ∗
      
      
       
        2
       
       
        t
       
      
     
    
   
   
     \frac{26!}{(26-t)!*t!*2^t} 
   
  
 (26−t)!∗t!∗2t26!​

种接线方式,如果有6根接线,

    t
   
   
    =
   
   
    6
   
  
  
   t=6
  
 
t=6,那么K1就有

 
  
   
    
     ∣
    
    
     K
    
    
     1
    
    
     ∣
    
    
     =
    
    
     
      
       26
      
      
       !
      
     
     
      
       (
      
      
       26
      
      
       −
      
      
       6
      
      
       )
      
      
       !
      
      
       ∗
      
      
       6
      
      
       !
      
      
       ∗
      
      
       
        2
       
       
        6
       
      
     
    
    
     =
    
    
     70
    
    
     ,
    
    
     605
    
    
     ,
    
    
     879
    
    
     ,
    
    
     373
    
    
     ,
    
    
     725
    
    
     ,
    
    
     696
    
    
     ,
    
    
     000
    
    
     ≈
    
    
     7
    
    
     ∗
    
    
     1
    
    
     
      0
     
     
      20
     
    
   
   
     |K1|=\frac{26!}{(26-6)!*6!*2^6} = 70,605,879,373,725,696,000\approx 7*10^{20} 
   
  
 ∣K1∣=(26−6)!∗6!∗2626!​=70,605,879,373,725,696,000≈7∗1020

总密钥空间大小:

     ∣
    
    
     K
    
    
     1
    
    
     ∣
    
    
     ∗
    
    
     ∣
    
    
     K
    
    
     2
    
    
     ∣
    
    
     =
    
    
     
      A
     
     
      5
     
     
      3
     
    
    
     ∗
    
    
     2
    
    
     
      6
     
     
      3
     
    
    
     ∗
    
    
     
      
       26
      
      
       !
      
     
     
      
       (
      
      
       26
      
      
       −
      
      
       6
      
      
       )
      
      
       !
      
      
       ∗
      
      
       6
      
      
       !
      
      
       ∗
      
      
       
        2
       
       
        6
       
      
     
    
    
     =
    
    
     4
    
    
     ,
    
    
     236
    
    
     ,
    
    
     352
    
    
     ,
    
    
     762
    
    
     ,
    
    
     423
    
    
     ,
    
    
     541
    
    
     ,
    
    
     760
    
    
     ,
    
    
     000
    
    
     ≈
    
    
     4
    
    
     ∗
    
    
     1
    
    
     
      0
     
     
      22
     
    
   
   
     |K1|*|K2|=A_5^3*26^3*\frac{26!}{(26-6)!*6!*2^6}=4,236,352,762,423,541,760,000\approx 4*10^{22} 
   
  
 ∣K1∣∗∣K2∣=A53​∗263∗(26−6)!∗6!∗2626!​=4,236,352,762,423,541,760,000≈4∗1022

​    可以看到接线板对整体密钥空间的扩大起重要作用。二战时期没有高速计算机,通过人工穷举密钥,对于这种数量级的密钥空间是不现实的。即使是使用计算机进行穷举,大部分电脑的单秒运算量在10的七次方到10的九次方之间,我们假设每秒穷举

    1
   
   
    
     0
    
    
     9
    
   
  
  
   10^9
  
 
109个密钥为例,筛选出正确密钥的期望时间约为

 
  
   
    400000
   
  
  
   400000
  
 
400000年。

​    除此之外,德军在使用Enigma机时还规定了一定的操作流程,他们在通信时,会先使用日秘钥加密一个会话秘钥,然后使用会话秘钥来加密明文。会话秘钥也是三个字母,德军先使用日秘钥加密会话秘钥两次,然后将这6个字母发送出去。比如日秘钥ABC,会话秘钥QWE,那么

    Q
   
   
    W
   
   
    E
   
   
    Q
   
   
    W
   
   
    E
   
   
    
     
      
       ⟶
      
     
     
      
       A
      
      
       B
      
      
       C
      
     
    
   
   
    D
   
   
    C
   
   
    Y
   
   
    X
   
   
    E
   
   
    V
   
  
  
   QWEQWE\stackrel{ABC}{\longrightarrow}DCYXEV
  
 
QWEQWE⟶ABC​DCYXEV,加密两边是为了防止出现错误。德军本意是为了保证每条信息都是用不同的密钥进行加密的,避免了使用同一个密钥加密过多内容而被破解者找到破绽。但是波兰人便是从这六个字母中找到了规律,实现了的初步的破解。但波兰的破解是不具有普遍性的,德军改进Enigma机和操作流程后便失效了。

1.4 加密算法实现

​ 这里我们用一个具体的字母举例,待加密字符为 ‘H’,K1,K2为题目所给,看一下加密算法的具体实现过程:

在这里插入图片描述

  1. 接线板K1

在键盘上输入字母H(7),H首先经过接线板(Stecker),发现H没有与其它字母相连,所以经过接线板后明文没有发生变化,仍为H(7)。

  1. 正向扰频器组合(Rotors)

首先通过密钥K2(4,4,16)将转子转动到相应位置。再将H(7)分别通过这三个转子。

H对应位置为7,将7作为输入通过快速转子,找到此时的第7个位置对应的左侧数字为11,再找到右侧对应的11,位置为6,所以经过快速转子,输出变为6。然后再以位置6作为输入通过中速转子,此时位置6对应的左侧数字为10,找到右侧对应的10,位置为23,经过中速转子,输出变为23。再将23作为输入通过慢速转子,位置23对应的左侧数字为13,找到右侧对应的13,位置为7。经过慢速转子,输出变为7。

  1. 反射器

正向扰频器输出的结果为7,将7作为输入通过反射器,输出结果为21。

  1. 逆向扰频器组合

将上一步的结果21作为输入先通过慢速转子,此时位置21对应的右侧数字为15,找到左侧对应的15,位置为25。同理,再依次通过中速转子输出变为24,最后通过快速转子输出变为20。

  1. 接线板K1

将20作为输入,通过逆向线路接线板,得到输出为12,对应字母为M。

最终M作为最终结果在显示灯板上显示出来。同理,可以对E进行类似的加密得到U。

关键函数

'''(整体被包装在类中,完整代码见压缩包 my_Enigma.py )'''defEncode_Decode(self,inputtext='',K2 =[]):if K2:'''可以通过显式提供K2来设置enigma机,K1一般不改变,只能通过self.SET函数设置'''
        self.SET(K2)if inputtext.isalpha():
        outputtext =""
        inputtext = inputtext.lower()for ch in inputtext:
            tmp =ord(ch)-97'''通过接线板'''
            tmp = self.K1[tmp]'''通过三个转子'''     
            tmp =(Cog_quick_re[(tmp + self.offset[0])%26]- self.offset[0]+26)%26 
            tmp =(Cog_mid_re[(tmp + self.offset[1])%26]- self.offset[1]+26)%26
            tmp =(Cog_slow_re[(tmp + self.offset[2])%26]- self.offset[2]+26)%26'''通过反射器'''
            tmp = T[tmp]'''通过三个轮子的逆'''
            tmp =(Cog_slow[(tmp + self.offset[2])%26]- self.offset[2]+26)%26
            tmp =(Cog_mid[(tmp + self.offset[1])%26]- self.offset[1]+26)%26
            tmp =(Cog_quick[(tmp + self.offset[0])%26]- self.offset[0]+26)%26'''通过接线板'''
            tmp = self.K1[tmp]
            outputtext +=chr(tmp+97)
            self.Rotate(1)#加密一个字符之后需要转动一下return outputtext

加密结果示意图:

在这里插入图片描述

​ 加密结果.png

二:Enigma解密

2.1 历史上的解密

​   ​ Enigma机在投入使用之后,英法的情报部门曾经尝试破解,但即使是最简单的3个转子,6对接线板的Enigma机,秘钥空间都有

    1
   
   
    
     0
    
    
     16
    
   
  
  
   10^{16}
  
 
1016的数量级,以当时的算力是不可能破解的。于是英法放弃了对Enigma机的破解,但是波兰面对黑云压城的德军,没有放弃的借口,破解Enigma机的第一次突破就来自波兰的数学家雷耶夫斯基(Marian Rejewski)。雷耶夫斯基通过数学分析,避免了接线板的转换,将秘钥空间降低到10万级别,然后就可以手动破解Enigma机了,参考Enigma机的破解一文。

​ ​    波兰人的工作可以破解比较简单的Enigma机,但是后来德军改进了Enigma机,比如增加转子数量,接线板交换的字母从6对增加到10对,使用日密钥加密会话密钥时不再加密两遍等,这些改进让波兰人的破解变的无效。1939年,德军入侵波兰,波兰人将Enigma机的复制品和掌握的破解方法提供给了英法。这也让之前轻易放弃破解的英法无比震惊和惭愧。接下来就是英国数学家图灵的表演时间了。

2.2 Enigma机破解原理

2.2.1 寻找明密文对关系 – Ciber

​ ​    因为Enigma反射器和转子的设计,所以在Enigma机加密过程中,一个字母是不会被加密成自身的。如上题H加密成M的过程,如果H被加密为自身,那么逆过程和正过程必须完全一致,而因为反射器的存在,正逆两个过程一定不会输出一样的结果。

​ ​    根据Enigma的这个性质,我们就可以猜测明文的几个单词,并找到他们可能的位置。在密文中猜测出几个单词的明文并不困难,因为德国人在信息正文中喜欢用固定的词组,比如Heil Hitler(希特勒万岁)等。英国人还发现德军喜欢在早上发送一条当天的天气预报,所以在早上6点钟截获的电文开头中肯定包含wetter(天气)这个单词。

​ ​    比如,我们用wetter在密文段上滑动比较,就可以确定wetter可能的位置,也就确定了它对应的密文,感觉可以理解为有限的选择明文攻击。

题目中所给:
在这里插入图片描述

在这里插入图片描述

2.2.2 通过环路屏蔽接线板

​ ​    在解题过程中,三个Ciber都经过尝试,这里用Ciber1来举例。

​ ​    Ciber1中有两个环路:

    H
   
   
    →
   
   
    L
   
   
    →
   
   
    D
   
   
    →
   
   
    H
   
  
  
   H\to L\to D\to H
  
 
H→L→D→H 和 

 
  
   
    E
   
   
    →
   
   
    L
   
   
    →
   
   
    O
   
   
    →
   
   
    E
   
  
  
   E\to L\to O\to E
  
 
E→L→O→E。我们把第一个环路展开,可以得到:

在这里插入图片描述
​   我们注意到,

    v
   
   
    2
   
  
  
   v2
  
 
v2 和 

 
  
   
    v
   
   
    
     2
    
    
     ′
    
   
  
  
   v2'
  
 
v2′ 是相等的,

 
  
   
    v
   
   
    3
   
  
  
   v3
  
 
v3 和 

 
  
   
    v
   
   
    
     3
    
    
     ′
    
   
  
  
   v3'
  
 
v3′ 是相等的,

 
  
   
    v
   
   
    4
   
  
  
   v4
  
 
v4 和 

 
  
   
    v
   
   
    1
   
  
  
   v1
  
 
v1 是相等的,我们将**相等的变量直接相连**,可以得到:

在这里插入图片描述

​ ​   这样就可以消除掉接线板的作用,我们要利用这个环,通过筛选缩小密钥空间。首先我们要遍历所有的转子组合,也就是

    26
   
   
    ∗
   
   
    26
   
   
    ∗
   
   
    26
   
   
    =
   
   
    17576
   
  
  
   26*26*26 = 17576
  
 
26∗26∗26=17576 种

 
  
   
    K
   
   
    2
   
  
  
   K2
  
 
K2,每一种

 
  
   
    K
   
   
    2
   
  
  
   K2
  
 
K2下,我们让v1遍历a-z,然后在上述转子状态下进行加密得到

 
  
   
    v
   
   
    2
   
   
    、
   
   
    v
   
   
    3
   
   
    、
   
   
    v
   
   
    4
   
  
  
   v2、v3、v4
  
 
v2、v3、v4,然后**判断
 
  
   
    
     v
    
    
     4
    
   
   
    v4
   
  
 v4是否和
 
  
   
    
     v
    
    
     1
    
   
   
    v1
   
  
 v1相等**,如果相等,说明这一组 

 
  
   
    [
   
   
    k
   
   
    2
   
   
    ,
   
   
    v
   
   
    1
   
   
    ]
   
  
  
   [k2,v1]
  
 
[k2,v1] 是满足这个环的。把所有的可能秘钥都记录下来形成一个较小的可能秘钥空间。

​ ​    前面提到,这个Ciber中还有另一个环

    E
   
   
    →
   
   
    L
   
   
    →
   
   
    O
   
   
    →
   
   
    E
   
  
  
   E\to L\to O\to E
  
 
E→L→O→E,此时我们只需要在第一个环筛选出的可能秘钥空间中,再用第二个环筛选一遍,就可以进一步缩小密钥空间。

秘钥筛选分析:

​ ​    我们在遍历的过程中,对于有一些k2,可以让某一个字母经过环之后加密成自身,但是有些k2不行,我们称前一种为

    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   possible K2
  
 
possibleK2,后一种为

 
  
   
    i
   
   
    m
   
   
    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   impossible K2
  
 
impossibleK2。对于

 
  
   
    i
   
   
    m
   
   
    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   impossible K2
  
 
impossibleK2,也就是说,在这种转子组合下,26个字母都不能被加密成自身。我们假设每个字母被加密后变成任一个字母的概率都是一样的,虽然这个假设对某一个k2是不合理的,但是考虑所有的秘钥空间,可以认为概率相等,那么

 
  
   
    i
   
   
    m
   
   
    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   impossible K2
  
 
impossibleK2就是一种”错排”,而这种”错排“一共有:

 
  
   
    
     
      D
     
     
      n
     
    
    
     =
    
    
     n
    
    
     !
    
    
     (
    
    
     
      1
     
     
      
       2
      
      
       !
      
     
    
    
     −
    
    
     
      1
     
     
      
       3
      
      
       !
      
     
    
    
     +
    
    
     .
    
    
     .
    
    
     .
    
    
     +
    
    
     (
    
    
     −
    
    
     1
    
    
     
      )
     
     
      n
     
    
    
     
      1
     
     
      
       n
      
      
       !
      
     
    
    
     )
    
   
   
     D_n = n!(\frac{1}{2!}-\frac{1}{3!}+...+(-1)^n\frac{1}{n!}) 
   
  
 Dn​=n!(2!1​−3!1​+...+(−1)nn!1​)

​ 总的字母排列有

    26
   
   
    !
   
  
  
   26!
  
 
26! 种,所以

 
  
   
    i
   
   
    m
   
   
    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   impossible K2
  
 
impossibleK2 的比例就是

 
  
   
    
     
      D
     
     
      26
     
    
    
     /
    
    
     26
    
    
     !
    
    
     =
    
    
     0.36787944117144245
    
   
   
     D_{26}/26! = 0.36787944117144245 
   
  
 D26​/26!=0.36787944117144245

​ ​    因为我们的转子的内部连线是不能更改的,只能对转子进行转动,因为我们的密钥空间没有26!那么大,但是经过筛选之后,发现,通过一个环路筛选出的

    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   possibleK2
  
 
possibleK2 占总

 
  
   
    K
   
   
    2
   
  
  
   K2
  
 
K2的比例是

 
  
   
    
     0.6281292671825216
    
    
     ≈
    
    
     1
    
    
     −
    
    
     
      D
     
     
      26
     
    
    
     /
    
    
     26
    
    
     !
    
   
   
     0.6281292671825216 \approx 1-D_{26}/26! 
   
  
 0.6281292671825216≈1−D26​/26!

​ ​    这也说明我们的假设是比较合理的,也可以说,我们的筛选结果是大概率是正确的。

2.2.3 还原接线板

​ ​   经过两个环路的筛选,我们得到了一组密钥空间

    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
  
  
   possibleK2
  
 
possibleK2和以及

 
  
   
    v
   
   
    1
   
  
  
   v1
  
 
v1的信息。再观察我们的环路:

在这里插入图片描述

​   我们在筛选过程中,用到的

    v
   
   
    1
   
   
    ,
   
   
    v
   
   
    2
   
   
    ,
   
   
    v
   
   
    3
   
  
  
   v1,v2,v3
  
 
v1,v2,v3,分别可以确定

 
  
   
    H
   
   
    ,
   
   
    L
   
   
    ,
   
   
    D
   
  
  
   H,L,D
  
 
H,L,D的接线关系,同理,另一个环路筛选出的

 
  
   
    v
   
   
    1
   
   
    ,
   
   
    v
   
   
    2
   
   
    ,
   
   
    v
   
   
    3
   
  
  
   v1,v2,v3
  
 
v1,v2,v3,也可以确定一部分接线关系,注意这里还存在一个接线板冲突的筛选。

​ ​    而我们的破解,是针对这一组明密文对应关系(一个

    C
   
   
    i
   
   
    b
   
   
    e
   
   
    r
   
  
  
   Ciber
  
 
Ciber)的,只要能找到一组转子组合

 
  
   
    K
   
   
    2
   
  
  
   K2
  
 
K2,接线板

 
  
   
    K
   
   
    1
   
  
  
   K1
  
 
K1,让

 
  
   
    H
   
   
    E
   
   
    L
   
   
    L
   
   
    O
   
   
    W
   
   
    O
   
   
    R
   
   
    L
   
   
    D
   
  
  
   HELLOWORLD
  
 
HELLOWORLD加密成

 
  
   
    L
   
   
    L
   
   
    D
   
   
    O
   
   
    N
   
   
    E
   
   
    E
   
   
    F
   
   
    G
   
   
    H
   
  
  
   LLDONEEFGH
  
 
LLDONEEFGH就可以了。那么,在某一组 

 
  
   
    [
   
   
    p
   
   
    o
   
   
    s
   
   
    s
   
   
    i
   
   
    b
   
   
    l
   
   
    e
   
   
    K
   
   
    2
   
   
    ,
   
   
    R
   
   
    i
   
   
    n
   
   
    g
   
   
    1
   
   
    [
   
   
    v
   
   
    1
   
   
    ,
   
   
    v
   
   
    2
   
   
    ,
   
   
    v
   
   
    3
   
   
    ]
   
   
    ,
   
   
    R
   
   
    i
   
   
    n
   
   
    g
   
   
    2
   
   
    [
   
   
    v
   
   
    1
   
   
    ,
   
   
    v
   
   
    2
   
   
    ,
   
   
    v
   
   
    3
   
   
    ]
   
   
    ]
   
  
  
   [possibleK2,Ring1[v1,v2,v3],Ring2[v1,v2,v3]]
  
 
[possibleK2,Ring1[v1,v2,v3],Ring2[v1,v2,v3]]中,只有几个字母的接线板是不确定的了,对于不能确定的字母,穷举一下字母表,判断是否存在接线板冲突,如果没有冲突,那么就认为这种接线是合理的。对于没有出现过的字母,我们这里默认他们是没有接线的,但是也有可能他们是有接线关系的,但是没有我们没有足够信息。因此我们有可能没有找到完全正确的接线板,只是找到了适用于

 
  
   
    C
   
   
    i
   
   
    b
   
   
    e
   
   
    r
   
  
  
   Ciber
  
 
Ciber的几种转子和接线组合。

2.3 解密算法实现

利用环路筛选秘钥,关键逻辑:

for x inrange(len(Ring)):ifnot x:
        enigma = Enigma()for i inrange(26):for j inrange(26):for k inrange(26):# i,j,k遍历所有转轮组合
                    flag =0
                    tmp =[]
                    k2 =[i,j,k]for v1 in ALPHA:# 对某一种转子组合和环路下,遍历字母表,查找是否有字母能加密为自身
                        enigma.SET(k2)
                        v4 = v1
                        v1v2v3=[]for r in Ring[x][0]:# Ring是环路的记录
                            v1v2v3.append(ord(v4)-97)if r :
                                enigma.Rotate(r)# 根据环路记录的相对位置调整转子
                            v4 = enigma.Encode_Decode(v4)# 加密if v4 == v1 :# 经过环路之后,判断是否等与自身
                            flag =1# 如果等于自身,意味着本次k2下,存在可能解,flag=1
                            tmp.append(v1v2v3)# 把环路加密过程中所有的过程变量都记录下if flag:                             
                        possible.append([k2,tmp])# 遍历字母表之后,再插入'秘钥可能'中,因为可能一个k2有多个解print(len(possible))

利用环路初步确定接线板:(见2.2.3的图)

'''两个环路'''
possibleK2 = Enigma_crackK2(1)print(len(possibleK2))
possibleK1 =[]# [[k2,K1],[k2,K1],...]
enigma = Enigma()for pos in possibleK2:
    k2 = pos[0]# 获取k2for v1v2v3 in pos[1]:# 获取第一个环的过程变量for v1v2v3_ in pos[2]:# 获取第二个环的过程变量if v1v2v3_[1]!= v1v2v3[1]:# 两个环路中存在的相同字母,对应接线板设置也肯定是一样的continue# 踩坑:注意continue和break的区别
            tmp_K1 =[-1]*26# 用于记录K1
            v1v2v3.append(v1v2v3_[0]) 
            v1v2v3.append(v1v2v3_[2])
            M =[7,11,3,4,14]# 通过两个环可以确定这5个字母的接线
            flag =0for i inrange(5):# 遍历这五个变量,更新tmp_K1
                result = K1_update(tmp_K1,M[i],v1v2v3[i])ifnot result:# 更新失败,说明有冲突,先break,再continue
                    flag =1breakif flag:continue
            possibleK1.append([k2,tmp_K1])# 经过两个环路筛选和接线板冲突后,所有可能的[k2,k1]print(len(possibleK1))

根据其他明密文对应还原接线板,关键逻辑:

tmp_possibleK1 =[]'''我们猜测的明文和其对应的密文中,只剩下几个字母的接线板还不能确定,通过加密判断筛选和穷举未知量,得到所有秘钥可能'''for pos in possibleK1:# 遍历现有的所有[k2,k1]
    k2 = pos[0]                 
    tmp_k1_0 = pos[1][:]
    P_E = tmp_k1_0[4]# P_E 代表P(E),即E经过接线板后的输出,经过上述过程后,这些量都是确定的
    P_L = tmp_k1_0[11]# L经过接线板后的输出P_L
    P_O = tmp_k1_0[14]# O经过接线板后的输出P_O'''未确定的对应关系:O-N,L-G'''
    enigma.SET(k2)
    enigma.Rotate(4)
    P_N =ord(enigma.Encode_Decode(chr(P_O+97)))-97# P_O是确定的,加密一下就得到P_N
    enigma.SET(k2)      
    enigma.Rotate(8)
    P_G =ord(enigma.Encode_Decode(chr(P_L+97)))-97# P_L是确定的,加密一下就得到P_Gif K1_update(tmp_k1_0,ord('n')-97,P_N)and K1_update(tmp_k1_0,ord('g')-97,P_G):# 判断计算得到的P_N和P_G是否冲突for P_W inrange(26):# 如果不冲突,再判断'W-E'的对应关系
            tmp_k1_1 = tmp_k1_0[:]
            enigma.SET(k2)
            enigma.Rotate(5)
            S_pw =ord(enigma.Encode_Decode(chr(P_W+97)))-97# S_pw = S(P(W)),因为P_E是已知的,遍历字母表,加密做判断,就可以找到P_Wif S_pw == P_E and K1_update(tmp_k1_1,ord('w')-97,P_W):for P_R inrange(26):# 最后确定'R-F'的关系,这两个的对应都不知道,只需要穷举P_R,计算P_F,并判断有无冲突即可
                    tmp_k1_2 = tmp_k1_1[:]
                    enigma.SET(k2)# 注意,每次计算最好都要重置enigma,因为enigma会自己动
                    enigma.Rotate(7)
                    P_F =ord(enigma.Encode_Decode(chr(P_R+97)))-97# 计算P_Fif K1_update(tmp_k1_2,ord('r')-97,P_R)and K1_update(tmp_k1_2,ord('f')-97,P_F):# 判断这一组R和F是否冲突for i inrange(26):#最后还剩下一些没有信息的数据,我们这里默认他们是没有接线的if tmp_k1_2[i]==-1:
                                tmp_k1_2[i]= i
                        tmp_possibleK1.append([k2,tmp_k1_2])
possibleK1 = tmp_possibleK1

参考文献https://www.zhihu.com/question/28397034

标签: 安全

本文转载自: https://blog.csdn.net/qq_52196579/article/details/126611318
版权归原作者 Mipiace 所有, 如有侵权,请联系我们删除。

“密码分析学-Enigma机破解”的评论:

还没有评论