中文译本 · 原作 Daniel Bourdeau《Unsolved Historical Ciphers》 以 CC BY 4.0 发布,本页由 JIC 翻译,非原作者官方版本,译文如有出入以英文原页为准 · 查看英文原页 ↗

东线,德军无线电通信 · ADFGVX(替换方阵加列换位) · 1918年11月

1918年11月的二十二条乱码 ADFGVX 电报

二十二条1918年11月来自东线的德军无线电报,列在 Klaus Schmeh 的“无法解密的 ADFGVX 电报”清单上。它们的密钥已于2017年公布;这些电报之所以解不开,是因为传输中丢失或多出了字母。这里套用已知密钥,并对每条电报搜索至多两个乱码块。其中九条已在2017年的评论帖中被解密,三条部分解密;这次搜索重现了这些结果,其余十条在十五把密钥中的任何一把下都得不出任何东西。

Daniel Bourdeau · 发布于 · 更新于 · 来源:Schmeh,五十强第46号,以及 George Lasry 提供的“Unsolved ADFGVX messages”页面;该帖下的70条评论(Norbert Biermann、Armin、Thomas、Max Baertl、George Lasry,2017年);Lasry、Niebel、Kopal 和 Wacker,Cryptologia 2017;James Rives Childs,German Military Ciphers from February to November 1918

方法:用已知密钥读出 · 范围:完整

现状 9 已解 · 3 部分 · 10 未解

清单条目应写作“22条电报,9条已解密,3条部分解密,10条未解”,而 Lasry 在评论帖中复原的那把密钥应与已公布的十四把并列。Norbert 2017年的方法——针对已知密钥做两处至多五个字母的块编辑——在此用一个德语语言模型重新实现,在不提供任何明文线索的情况下重新推出了已解的各页。对十条未解电报,它用十五把密钥中的任何一把都一无所获;而在这样的长度下,不依赖密钥的攻击即便在人为植入的对照上也无法复原换位。这十条未解电报需要 Childs 的原件,或者一把从未出现在语料中的密钥。

01 这份清单是什么

James Rives Childs 是1918年派驻法军的美国密码分析员,他保存了一份在东线截获的德军 ADFGVX 通信的抄本。2017年,George Lasry、Ingo Niebel、Nils Kopal 和 Arno Wacker 用针对换位的爬山法攻破了这批语料,在1918年9月至12月的十四把三日密钥下复原了618份密码电报。随后 Lasry 把在这些密钥下都无法解密的电报列成清单交给 Klaus Schmeh,Schmeh 以“Unsolved ADFGVX messages from World War I”为题发表,附上了密钥,后来又将其列为他的五十强第46号。

Lasry 在那个页面上的附注点明了问题所在:这些密钥“most certainly all the keys used during the period”,所以“the challenge is to understand how the cryptograms were mutilated”。ADFGVX 对长度毫不宽容。列换位按密钥长度切分字母流,所以丢失或多出一个字母,就会让其后的每个列边界都移位,把电报的其余部分变成噪声。一条有两处乱码的电报,即使密钥已知,也无法再用该密钥解密。

2017年2月至9月间,该帖下的评论区完成了大部分工作。Norbert Biermann、Armin、Thomas、Max Baertl 和 Lasry 本人一条接一条地解密了电报。Schmeh 宣布要写一篇汇总文章,却始终没写,所以这些解密结果只零散地存在于评论中,无论印本还是网上都找不到结果汇总表。本报告做的第一件事就是发布这张表。

02 密钥,转成机器可读格式

Lasry 的清单把每把密钥给成一个换位排列和一个36字符的替换方阵,各单元按 A D F G V X 的行序排列。十四个方阵中有三个含有成串的连字符,表示从未复原的单元,而 PDF 的文本层把这些连字符串压缩成了短破折号和长破折号,使方阵只剩34或35个字符。把每个破折号还原成能凑足36个字符的连字符串长度,三个方阵就都修复了。全部十四把都在 keys.json.

密钥数字有两种解释。要么 perm[i] 是第 i 个输出的列,要么是第 i 列被输出的位置。两种解释都能自洽地往返,所以加密–解密测试无法区分它们。解密一条真实电报则可以。答案是第二种。

不在清单上的密钥

2017年5月3日,Lasry 在评论帖中报告:一条分成两部分的电报——11月13日的 FFVXV 密码电报及其后续的 AFAFF 残片——在一把不属于十四个时段中任何一个的密钥下合并解密成功:换位词 CMBLAKOHIDENFJGP,长度16。他给出了合并后的明文,共173个字母,并指出他的程序需要全部356个密文字母才能复原一把长度为16的密钥。替换方阵没有公布。这里把两份密码电报中未换位的双字母组与他的明文(已采用 Norbert 的修正)对齐,重建了方阵:36个单元中复原了24个,数字和字母 M、Q、Y 未能复原,因为这条电报从未用到它们。它是以下文件中的第十五个条目: keys.json 仓库的笔记称之为 CHI 密钥,名称取自它所加密的那条电报的报头。

03 2017年的成果汇成一表

评论帖的全部70条评论都逐一看过。页码是 Schmeh 所印的 Childs 抄本页码;清单上有两条电报没有页码。字母数是收到的密文字母数,印本转录中标出的缺口另行计数。每项解密都归功于最先贴出它的人。

Childs 页码字母数状态密钥读解
73176 + 2处缺口未解无一相符—
100122已解11月1–3日KEINE STOERUNG DURCH FEIND X MITTAGS 2 FEINDL X DIV X IM MARSCH AUF BELGRAD X(Armin)
105290已解11月1–3日GERMANIA ETAPPE KONSTANTINOPEL XX FUER MITTELMEER DIVISION ZU X TEL X NR X 62 X DIV X TELEGR X NR X 58 X ERSTELLT … VOM X 4 X NOVEMBER ERLEDIGT X ADMIRALSTAB(Norbert)
109258已解11月1–3日O X K X M X ABENDMELDUNG … UNTERBRINGUNG LETZTER TEILE BEENDET X 1 WEITERER DU X DIV 5 IM MARSCH AUF BELGRADER KAVV X 2 X SONST KEINE EREIGNISSE(Norbert)
132153 + 缺口已解11月4–6日FUER EILVESE X WIEDERHOLE TELEGR X VON VIERTER PERIODE IN FUENFTER X GEBETSORDER 5 MIN X VVV。加密者把 VV 写成了 VVV,因此长度是奇数(Norbert)
146244已解11月4–6日FUNKSTELLE KERTSCH ER HAT BETRIEB X 1F X RUFNAMEN RICHARD EMIL KARL X FUNKSTELLEN DORTIGEN BEREICHS BENACHRICHTIGEN X NACHRICHTENCHEF 4B X 7834 X(Norbert)
152104未解无一相符—
153(VFVAX)132未解无一相符,包括 CHI 密钥—
153(AXVAA)93 + 15处缺口未解无一相符,包括 CHI 密钥—
158240 + 2处缺口未解无一相符—
164 (F-G-X)158 + 44处缺口部分11月7–9日… X 9 X 11 X TEMESVAR X … DIE VON X MIRCO NACH WESTEN UND SUEDEN WEG X LEIDER WEGE VOM GEGNER BESETZT X(Norbert)
164(VFGAG)136 + 44处缺口部分11月7–9日EL X DIE HOEHE X 828 X O X H X L X MIRCO X SONST KEINE EREIGNISSE VON BEDEUTUNG XX(Norbert)
170106未解无一相符—
171310 + 4处缺口已解11月7–9日IN UKRAINE UND POLEN RUBELKURSE STARK STEIGEND INFOLGE BRUCHES ZWISCHEN DEUTSCHLAND UND SOWJETREGIERUNG UND ERWARTUNG DER WIEDERHERSTELLUNG RUSSLANDS DURCH DEUTSCHLAND UND ENTENTE(Norbert)
176(“缺10个字母”)214已解11月10–12日DURCHBRUCH VORBEREITET X DURCHBRUCHSRICHTUNG NACH NORDEN ODER NORDOSTEN ERFOLGEN WIRD X KANN JETZT NOCH NICHT BEURTEILT WERDEN X(Norbert)
176(GGDAA)220未解无一相符—
无页码(VGADA;Childs p. 215,11月22日)237 + 11处缺口部分11月22–24日ABS X MIDIV 5 X EILMELDG … ARMADA KERTSCH X BRINGT ENTENTE FLOTTE ZWO DIVISIONEN X NEUSEELAENDER X ENGL X U X FRANZO X MIT X … OHL X KORPS …(Norbert、Baertl)
187(FFVXV;Childs p. 191,11月13日,第1部分)212已解CHI,11月13日RUSSISCHEN UND POLN HEERESVERKEHR VOLL ERFASSEN X WICHTIGES BESONDERS AUS POLN VERKEHR UEBER OHL STATION VERZIFFERT FUNKEN(Lasry、Norbert)
无页码(AFAFF;第2部分)142已解CHI,11月13日SOWEIT FERNSCHREIBERVERBDG NICHT ARBEITET X REST SCHRIFTLICH X NACH CHEF(Lasry、Norbert)
18984 + 6处缺口未解无一相符—
198165未解无一相符—
217170未解无一相符—

九条已解密,三条部分解密,十条在任何地方都找不到解密结果。另有一页抄本,即印本中的187(SELLV…,“Stellv. Gen. Kom. 9 AK Breslau”),是卡塞尔团队早已解出的电报,不应列入清单;Lasry 在评论帖中已指出这一点。两条 CHI 电报被列为在已公布密钥下无法解密,这没错;它们是在 Lasry 复原了一把未公布的密钥之后才解密的。

04 重新实现 Norbert 的方法

Norbert 用一句话说明了他的方法:在两个不同位置添加或删除至多五个字符,穷举搜索,用 n 元组评价函数为结果排序。 blocks.py 做的正是这件事。对十五把密钥中的每一把,以及每一种至多两处、每处一到五个字母的块编辑(在抄本的五字母组边界处插入或删除),它都进行解密,并用一个德语四元组模型为结果打分;该模型由 Gutenberg 德语文本中的360万个字母构建(lm_de.py)。含有数字或未复原单元的窗口记最低分;跨越 X 分隔符的窗口,代价低于乱码、高于正文。在这个模型上,德语散文每个窗口的得分约为 −3.3 nats,随机字母约为 −7。

在不提供任何明文线索的情况下,搜索重新推出了第105、109、146、171页,第176页那条“缺10个字母”的电报,以及两条 CHI 电报。在第146页上,Norbert 在第10组之前插入的那个五字母块得出为 (45, 5)。在第176页的电报上,两个五字母块得出为 (10, 5), (130, 5)。第100页用同样的搜索、只插入一个双字母块就解开了。搜索还找到了无页码的 VGADA 电报在11月22–24日密钥下的部分解。在印本转录标出缺口之处, gaps.py 把缺口还原到各自的组里,再用模拟退火处理剩余的单字母丢失;在第132页上,它在没有任何提示的情况下得出了 Norbert 的文本。

重新推出的各页得分(取自运行日志),与未解电报所能达到的最佳得分对比:

页码密钥长度最佳得分,nats/窗口搜索返回的解密结果
187(CHI 第1部分)16−4.45RUSSISCHETUNDPOLNHEERESVERKEHRVOLLERFASSENXWICHTIGESBESONDERS…
14617−5.25FUNKSTELLEKERTSCHERHAE.TAB12X1.XRUFNAME.RICHARD.MILKARLX…
AFAFF(CHI 第2部分)16−5.28SOWEITFERNSCHREIBERVERBDGNITHTARBEICETXRESTSCHRIFTLICHXNACHCHEF…
10019−5.39KEI.ESTOERFNGDURCHFEINDXMITTAGS2FEINDLXDIVXIMMARSCHAUFBELGRAD.
17120−5.50INUKRAI.EUNDPOLEN.UBELKURSETARKSIEIGENDINFOLGEBRUCHEEZWISCHEN…
10519−6.02GERMANIAATAPPEKONSTANTINOPELX6FUERMITTJLMEERDIVISIVNZUXTELXNRX62…
10919−6.02OXFXMXABECDMELUNGXS4VCXUMBJRGABGLETZTEVTEILEBEEVUKTX1WEITEDE…
最佳的未解电报(158,170)20, 19−6.89噪声

已解的各页即便块编辑不完全准确,也一眼就能认出是德语,剩下的乱码是第二轮能修复的单字母丢失。第105页和第109页两行得分比其他的低,因为两块搜索只能近似其损坏情况;但两段文本在原始输出中都清晰可读,也都与 Norbert 2017年的解密一致。

05 检验十条未解电报

两处块编辑,十五把密钥

十条电报中的每一条都用全部十五把密钥、至多两处块编辑跑过一遍。每条的最佳结果,取自 blocks_out.txt:

页码字母数最佳结果的密钥长度最佳得分输出
7317622−7.12DWR5C10WAXWBI.GWBXD1QGRA.R7OCW3Q…
15210422−6.76YPVXKTHJ7EM46PGPQ3RONDSEEUHXKTAX…
153(两条)132, 9320−6.99XWH2XBB3WATECOIFLUKTXMHK17SSY2ME…
15824020−6.89ZF2B0GEKJXII32RXRCO4LRS2DXA2RBDO…
17010619−6.89N5ADB08EKYND918UFEED92H3ELZEJ0UA…
176(GGDAA)22022−7.10RGXCXXPPUN6RAXZK2YD8PMRX4NVX4ZYT…
1898422−7.081AA1SLUOXO.VGXWUXUWH6LXXNHLV.9WW…
19816520−6.97LTDUUKWRA28KK61UITPUU31LEPXSIP42…
21717018−7.04YBEIEU84543EOTXT45R8K6XXGCSF4PWI…

没有一条超过 −6.7。同一次运行中,已解电报的得分在 −4.4 到 −6.0 之间,随机字母约为 −7.3。所以这十条中没有一条是用十五把密钥之一加密、且只有两处或更少块损坏的,这恰恰是2017年的读者们到达并止步的边界。输出中数字很多,通常是密钥不对的迹象:这里的真实通信大多是字母,错误的方阵会把双字母组散布到数字单元上。

用 CHI 密钥试第153页的两条电报

2017年9月,Norbert 提出(但未测试)第153页的两条电报可能属于 CHI 密钥,因为它们出自同一时期。用奇偶修复直接解密,以及块搜索,对两条电报返回的都是噪声。原因要么是还有另一把未列出的密钥,要么是损坏超过了两块。

不依赖密钥的攻击,以及它为何失败

如果某些未解电报是用语料之外的密钥加密的,那么这把密钥就只能仅凭密文来复原。 keyless.py 的做法是:在每个候选长度上,以逆换位产生的字母对的重合指数为目标,对列序做模拟退火(因为正确的逆换位会把单表替换的双字母组配成对),然后用德语模型求解36符号的替换。在用于未解电报之前,先在一个人为植入的对照上运行:224个德语字母,用同样设计的长度为19的密钥加密。

候选长度1516171819(真实)20212223
退火后的字母对重合指数0.0550.0480.0600.0530.0640.0580.0660.0630.073

真实长度并不突出:19处的峰值被21、22和23超过,替换阶段在任何长度上都不收敛。对照没有被复原。Lasry 专为此目的编写的程序,需要356个字母才能复原一把长度为16的密钥。十条未解电报的长度在84到240个字母之间。因此在这样的长度下,不依赖密钥的复原是做不到的,只有一个例外:两条或更多共用同一把未知密钥的未解电报可以合并求解,就像那两条 CHI 电报一样。密文中没有任何东西表明哪些电报属于这种情况;而最自然的候选——第153页的两条电报——放在一起试,也一无所获。

06 现状,以及什么能改变它

九条电报已解密,三条部分解密,十条未解。这十条于2026年9月经过检验,在每一把已知密钥、至多两处块编辑之下都失败了。有三件事能改变这一点。

什么为何重要
Childs 的原件这十条中有几条在印本转录中带有明确的缺口标记,其中一条标着“缺10个字母”。Schmeh 印出的转录是抄本的抄本;截获原件上可能保留着搜索不得不去猜的那些字母。
另一把密钥CHI 电报证明了公布的清单并不完整。一把从其他来源、或从同一时期某条从未列入本清单的较长电报中复原的密钥,几秒钟内就能对全部十条进行测试。
超过两处编辑的搜索在十五把密钥上做三处块编辑,计算量是够得着的,也是自然的下一步;这里没有运行,是因为两处编辑这一标准已经解出了2017年读者们解出的一切,而且得分没有显示任何未解电报接近解开。

在其中任何一项出现之前,有用的成果是:上面的表格,十五把机器可读格式的密钥(三个受损方阵已修复,CHI 方阵已重建),以及一个无需提供明文就能重现2017年解密结果的解码器。

07 文件

文件内容
targets/adfgvx/msgs.txtSchmeh 所印的二十二份密码电报,保留缺口标记
targets/adfgvx/keys.json十五把密钥:Lasry 的十四把(三个受损方阵已修复),以及11月13日的 CHI 密钥
targets/adfgvx/key16.py根据两部分明文重建 CHI 替换方阵
targets/adfgvx/repair.py解码器; validate 重现第100页, solve 对所有电报运行插入搜索
targets/adfgvx/blocks.pyNorbert 的两处块编辑搜索,针对所有密钥;输出在 blocks_out.txt
targets/adfgvx/gaps.py识别缺口的解析器,以及处理剩余单字母丢失的退火程序
targets/adfgvx/lm_de.py德语四元组模型,Gutenberg 德语文本中的360万个字母
targets/adfgvx/keyless.py不依赖密钥的换位攻击;对照输出在 kl_control224.txt
research/top50/arts/46_comments.txt2017年评论帖的70条评论,文本
targets/adfgvx/NOTES.md工作笔记,两次会话