ENIGMA密码机程序

ENIGMA是一种复式替换序列密码体系,所谓序列密码,是指加密不分组,加密后的信息与加密前是等长的,简化了对通信buf的处理。它的强度并非很高。在商业通信中,完全不加密是危险的,过于复杂的加密也没必要。就像我们家庭,没必要像国库的安全级别,但也不能不锁门,我们通常使用的弹子锁,就是一种经济简便的安全措施。。

直到第一次世界大战结束为止,所有密码都是使用手工来编码的。直接了当地说,就是铅笔加纸的方式。在我国,邮电局电报编码和译码直到很晚(大概是上个世纪八十年代初)还在使用这种手工方法。手工编码的方式给使用密码的一方带来很多的不便。首先,这使得发送信息的效率极其低下。明文(就是没有经过加密的原始文本)必须由加密员人工一个一个字母地转换为密文。考虑到不能多次重复同一种明文到密文的转换方式(这很容易使敌人猜出这种转换方式),和民用的电报编码解码不同,加密人员并不能把转换方式牢记于心。转换通常是采用查表的方法,所查表又每日不同,所以解码速度极慢。而接收密码一方又要用同样的方式将密文转为明文。其次,这种效率的低下的手工操作也使得许多复杂的保密性能更好的加密方法不能被实际应用,而简单的加密方法根本不能抵挡解密学的威力。

解密一方当时正值春风得意之时,几百年来被认为坚不可破的维吉耐尔(Vigenere)密码和它的变种也被破解。而无线电报的发明,使得截获密文易如反掌。无论是军事方面还是民用商业方面都需要一种可靠而又有效的方法来保证通讯的安全。

1918年,德国发明家亚瑟·谢尔比乌斯(ArthurScherbius)和他的朋友理查德·里特(RichardRitter)创办了谢尔比乌斯和里特公司。这是一家专营把新技术转化为应用方面的企业,很象现在的高新技术公司,利润不小,可是风险也很大。谢尔比乌斯负责研究和开发方面,紧追当时的新潮流。他曾在汉诺威和慕尼黑研究过电气应用,他的一个想法就是要用二十世纪的电气技术来取代那种过时的铅笔加纸的加密方法。

谢尔比乌斯发明的加密电子机械名叫ENIGMA,在以后的年代里,它将被证明是有史以来最为可靠的加密系统之一,而对这种可靠性的盲目乐观,又使它的使用者遭到了灭顶之灾。这是后话,暂且不提。

ENIGMA看起来是一个装满了复杂而精致的元件的盒子。不过要是我们把它打开来,就可以看到它可以被分解成相当简单的几部分。下面的图是它的最基本部分的示意图,我们可以看见它的三个部分:键盘、转子和显示器。

在上面ENIGMA的照片上,我们看见水平面板的下面部分就是键盘,一共有26个键,键盘排列接近我们现在使用的计算机键盘。为了使消息尽量地短和更难以破译,空格和标点符号都被省略。在示意图中我们只画了六个键。实物照片中,键盘上方就是显示器,它由标示了同样字母的26个小灯组成,当键盘上的某个键被按下时,和此字母被加密后的密文相对应的小灯就在显示器上亮起来。同样地,在示意图上我们只画了六个小灯。在显示器的上方是三个转子,它们的主要部分隐藏在面板之下,在示意图中我们暂时只画了一个转子。

键盘、转子和显示器由电线相连,转子本身也集成了6条线路(在实物中是26条),把键盘的信号对应到显示器不同的小灯上去。在示意图中我们可以看到,如果按下a键,那么灯B就会亮,这意味着a被加密成了B。同样地我们看到,b被加密成了A,c被加密成了D,d被加密成了F,e被加密成了E,f被加密成了C。于是如果我们在键盘上依次键入cafe(咖啡),显示器上就会依次显示DBCE。这是最简单的加密方法之一,把每一个字母都按一一对应的方法替换为另一个字母,这样的加密方式叫做“简单替换密码” 。

  1  cat enigma1.c
  2
  3 #include <stdio.h>
  4
  5 #include <netcom.h>
  6
  7 #include <crc32.h>
  8
  9 /*
 10
 11  *      A one-rotor machine designed along the lines of Enigma
 12
 13  *      but considerably trivialized.
 14
 15  */
 16
 17 char *des_fcrypt();
 18
 19 char *crypt();
 20
 21 #define ECHO 010
 22
 23 #include <stdio.h>
 24
 25 #define MASK 0377
 26
 27
 28
 29
 30
 31 /* 生成密码轮 */
 32
 33 static enigma1_setup(pw,salt,conn)
 34
 35 char *pw,*salt;
 36
 37 struct crypt_s *conn;
 38
 39 {
 40
 41 int ic, i, k, temp;
 42
 43 unsigned random,seed;
 44
 45 char *buf,buf1[20];
 46
 47 char    *t1;
 48
 49 char    *t2;
 50
 51 char    *t3;
 52
 53
 54
 55         t1=conn->t1;
 56
 57         t2=conn->t2;
 58
 59         t3=conn->t3;
 60
 61         seed=ssh_crc32(pw,strlen(pw)); // seed=123;
 62
 63
 64
 65         buf=des_fcrypt(pw,salt,buf1);
 66
 67         for (i=0; i<13; i++)
 68
 69                 seed = seed*buf[i] + i;
 70
 71         for(i=0;i<ROTORSZ;i++) {
 72
 73                 t1[i] = i;
 74
 75                 t3[i] = 0;
 76
 77         }
 78
 79         for(i=0;i<ROTORSZ;i++) {
 80
 81                 seed = 5*seed + buf[i%13];
 82
 83                 random = seed % 65521;  //random(key);
 84
 85 /* 生成主编码轮 t1 */
 86
 87                 k = ROTORSZ-1 - i;
 88
 89                 ic = (random&MASK)%(k+1);
 90
 91
 92
 93                 temp = t1[k];
 94
 95                 t1[k] = t1[ic];
 96
 97                 t1[ic] = temp;
 98
 99 /************************************************************************
100
101  * 生成反射板 反射板只要不重不漏的把各点两两连接起来?
102
103  * 可以随机的
104
105  ************************************************************************/
106
107                 if(t3[k]!=0) continue;
108
109                 random >>= 8;
110
111                 ic = (random&MASK) % k;
112
113                 while(t3[ic]!=0) ic = (ic+1) % k;
114
115                 t3[k] = ic;
116
117                 t3[ic] = k;
118
119         }
120
121 /* t2为t1的逆 */
122
123         for(i=0;i<ROTORSZ;i++)
124
125                 t2[t1[i]&MASK] = i;
126
127 }
128
129
130
131 void enigma1(pass, salt,string,len,conn)
132
133 char *pass,*string,*salt;
134
135 int len;
136
137 struct crypt_s *conn;
138
139 {
140
141 register char *p;
142
143 register int  k;
144
145 int  n1;
146
147 int n2;
148
149 char *t1,*t2,*t3;
150
151
152
153         if(!conn->pw||strncmp(conn->pw,pass,strlen(conn->pw))||strncmp(conn->salt,salt,2)) {
154
155                 strncpy(conn->pw,pass,PWLEN);
156
157                 strncpy(conn->salt,salt,SALTLEN);
158
159                 conn->pw[PWLEN]=0;
160
161                 conn->salt[SALTLEN]=0;
162
163                 enigma1_setup(conn->pw,conn->salt,conn);
164
165         }
166
167         n2=n1 = 0;
168
169         p=string;
170
171         t1=conn->t1;
172
173         t2=conn->t2;
174
175         t3=conn->t3;
176
177
178
179         for(k=0;k<len;k++){
180
181                 *p++ = t2[(t3[(t1[(*p+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1;
182
183                 if(++n1==ROTORSZ) {
184
185                         n1 = 0;
186
187                         if(++n2==ROTORSZ) n2 = 0;
188
189                 }
190
191         }
192
193 }
194
195 其中netcom.h中所需的内容:
196
197 #define ROTORSZ 256
198
199 #define PWLEN 16
200
201 #define SALTLEN 2
202
203 struct crypt_s {
204
205         char    pw[PWLEN+1];
206
207         char    salt[SALTLEN+1];
208
209         char t1[ROTORSZ];               /* pass.c: ROTORSZ*/
210
211         char t2[ROTORSZ];
212
213         char t3[ROTORSZ];
214
215 };
216
217
218
219 Demo程序:
220
221 #include <stdio.h>
222
223 #include<netcom.h>
224
225
226
227 extern void enigma1(char *key,char *salt,char *string,int len,struct crypt_s *enigma_s);
228
229
230
231 int main(int ac,char *av[])
232
233 {
234
235 char buf[131702];
236
237 char *key="agh57Dsar_~3C";
238
239 int len,i,len1;
240
241 struct crypt_s enis;
242
243
244
245         *enis.salt=0;
246
247         memset(buf,‘A‘,sizeof(buf));
248
249         buf[sizeof(buf)-1]=0;
250
251         while(!ferror(stdin)) {
252
253                 fgets(buf,sizeof(buf),stdin);
254
255                 if(feof(stdin)) break;
256
257                 TRIM(buf);
258
259                 len=strlen(buf);
260
261                 enigma1(key+2,key,buf,len,&enis);
262
263                 len1=len>30?30:len;
264
265                 for(i=0;i<len1;i++) printf("%02X ",buf[i]&255);
266
267                 printf("\n");
268
269                 enigma1(key+2,key,buf,len,&enis);
270
271                 printf("%.100s\n",buf);
272
273
274
275         }
276
277         return 0;
278
279 }
280
281  

这是一个单轮带反射器的ENIGMA加密/解密机。256个位置的转轮,可加密二进制字节信息。反射器可以转动,等价一个编码轮,或称为反射轮。它的序列长度为64K,比ENIGMA的17576长。ENIGMA之所以被破解,源于它只有3个转轮,敌方得到了这3个转轮,又得知每次3个转轮的排列、起始位置、插线板设置,就完全破解了。

我们在SDBC中的使用,每次连接时动态生成密钥,密钥是非常随机的,等于有无数个转轮。如果要破解此密码,可以设法再生t1码轮和t3反射轮(这可是相当于长达512字节的密钥),这似乎是比较困难的。再有就是对密钥的强力攻击了,这个程序是采用crypt密钥生成转轮的,强度等同于crypt。当然,也可以采用强度更高的算法生成转轮。这个算法是否应该再增加一些转轮来提高强度?我认为没必要。它主要用于网络通信,数据包通常都不会超过64K,增加转轮不过是增加序列长度,超过64K的序列并无意义,却要大幅度增加开销。

SDBC使用这个程序,基本都属于短时效数据,经过长时间破解了,已经没有意义。对于长时效数据,用户应该采用其他方法自行加密。而SDBC是支持二进制数据传输的。

时间: 2024-10-12 16:17:08

ENIGMA密码机程序的相关文章

Enigma Sim-英格玛密码机模拟器

Enigma Sim是一款Enigma(英格玛)密码机模拟软件,能够对信息进行多表代换加密.该模拟器高度还原了二战时期德国所使用的三种型号Enigma的功能和细节,转子和反射器所对应的字母代换表都参考了历史上真实的Enigma密码机数据.用户通过设定转子型号.转子起始位置.反射器型号以及插线板来设定加密密码,之后可以对输入的明文信息进行加密.解密信息的一方如果知道密码的具体设定便可以将信息还原. App Store Link: comming soon...      软件特色: ·模拟三种En

加密的盐

明文总是有一些不随机的冗余信息的,特别是公文.报告等格式文件.二战中,德军使用恩尼格玛ENIGMA转子密码机加密他们的电报,建立了一个在当时十分高效的加密系统.这一系统在战争前期给盟军的情报工作带来很大的麻烦.德军的一些定期报告有着固定的格式和行文模式,这些明文中的固定成分是盟军知道的.图灵发明的密钥分析机,利用了这些固定成分加速猜测过程和检验猜测结果.德国密码专家并非不知道这一点,ENIGMA密码机要求发报员先键入3个随机字符,然后才能键入明文.这三个随机字符会使密码机进入一个随机初态,以避免

关于编程的历史

首先编程语言是一组用来定义计算机程序的语法规则.它是一种被标准化的交流语言,用来向计算机发出指令.一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动.尽管人们多次试图创造一种通用的程序设计语言,却没有一次尝试是成功的.之所以有那么多种不同的编程语言存在的原因是设计程序语言的初衷不同,对语言学习曲线的追求不同,不同程序之间的运行成本差异等. 其发展历程: 编程语言的历史早于真正意义的计算机的出现.19世纪就有"可编程的"织布机和钢琴弹奏装

一些基础密码算法的实现

把以前写过的几个小算法稍整理下子. 1.多表替代密码: 1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<string> 5 using namespace std; 6 7 int gcd(int a,int b); //求最大公约数: 8 void jiam(string words,int* A);//加密: 9 void jiem(string words,i

计算机科学发展的动力

姚尧 计算机对现代人来说并不陌生.我常常在坐车或者吃饭时和不是学计算机的朋友闲聊.出乎意料的是他们总会认为学计算机就是学会十分懂得如何组装电脑.如何重装操作系统,或者如何入侵他人的计算机做一些破坏活动,至少从话语表面上看如此. 不错,设计硬件体系结构.编写操作系统和网络安全攻防属于计算机科学领域研究的问题.但很少有人问:为什么现在到处都是冯诺依曼体系结构.Windows操作系统.这样充满问题的计算机网络呢?如果要回答这些问题,就必须讨论到计算机发展的深层理由:为什么也称学习计算机也是学习一门科学

成为专业程序员路上用到的各种优秀资料、神器及框架

最近想着怎么把自己的知识体系进行整理起来,使用思维导图进行描述,对自己以后的发展也有一个更深的认识,更快的提升自己:看到了下面这篇文章,感觉非常实用,从语言到框架都非常全面,自己也可以继续补充,也是对自己知识体系的一个补充吧. 前言 成为一名专业程序员的道路上,需要坚持练习.学习与积累,技术方面既要有一定的广度,更要有自己的深度. 笔者作为一位tool mad,将工作以来用到的各种优秀资料.神器及框架整理在此,毕竟好记性不如烂键盘,此项目可以作为自己的不时之需. 本人喜欢折腾,记录的东西也比较杂

【真正福利】成为专业程序员路上用到的各种优秀资料、神器及框架

转载,原地址:http://www.cnblogs.com/jasondan/p/6380597.html 据说看到好文章不推荐的人,服务器容易宕机!本文版权归翟士丹(Stan Zhai)和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利. 好东西不是随便收集下,发篇博文,骗些点赞的!积累了5年多的东西,是时候放出来跟大家见见面了. 或许有的园友在14年的时候收藏过我的一篇"工欲善其事.必先利其器"的博文,时隔3年,已经

Qt技巧:Win7下打包发布Qt程序(解释的比较清楚,把exe和dll伪装合并成一个文件)

转自:http://www.stardrad.com/blog/qt-5%E7%A8%8B%E5%BA%8F%E5%9C%A8windows%E4%B8%8A%E7%9A%84%E5%8F%91%E5%B8%83/ http://blog.163.com/[email protected]/blog/static/1582209320132291718389/ 最近做了个qt的程序,但是发布程序比较困难,因为qt5有着比较多的dll,如下两篇详述了qt dll依赖库,以及如何查询自己工程所用的d

Qt 程序在 Windows 下的发布

本文讨论在 Windows 平台下编译成功的 Qt 程序,如何在未配置 Qt 开发环境的 Windows 平台下独立运行的方法. 经过验证发现,在 Ubuntu 平台下编译成功的程序可在未安装 Qt 开发环境下的 Ubuntu16.04 中运行,所以,本文仅讨论,在 Windows 平台下编译成功的 Qt 程序,在未配置 Qt 开发环境的 Windows 平台下独立运行的方法. 1. 编译模式选择 如若想要发布程序,在 IDE 中编译一定要选择 release 而不是 debug,编译成 rel