古老的加密技术

移动开发
看看在历史上我们是如何隐藏私密信息的,第一个被最广泛熟知的加密方式就是公元前 58 年的凯撒加密(Caesar cipher)

看在历史上我们是如何隐藏私密信息的

凯撒加密

***个被最广泛熟知的加密方式就是公元前 58 年的凯撒加密(Caesar cipher)

加密

凯撒加密的加密方式就是,在加解密之初,加解密的双方需要先确定一个位移长度。加密的一方通过对明文中的单词按照选定的平移长度逐个的进行平移,得到加密后的内容;解密的一方通过将密文按照选定的平移长度进行逆向的平移,则可以得出明文。

比如,对于加密条件 明文为 hello,平移长度为 3 的加密过程:

  1. 根据 26 个英文字母的顺序,h 向后推 3 个的字母为 k
  2. 按照***步对剩余的明文字母依次类推,可以得出密文为 khoor

破解

对于凯撒加密,其破解的关键有两点:

  1. 明文所采用的语言中的字母出现频率的统计图表(可以通过大量的统计分析该语言的书籍)
  2. 对密文进行大量统计得出的其中其母出现的频率图表
  3. 第1步和第2步得出的图表进行简单的位移就可以得知加密采用的位移

之所以可以这样去破解凯撒加密,是因为人类的语言实际是一个具有规律的事物,而语言中的各个字母出现的频率也是这个规律的一部分(这一点常常容易被忽略)。对于选定的位移,实际上只是将原有的字母频率图表做了一个平移 - 因为每一个字母都平移了固定的长度。

多字码加密

15 世纪中叶,加密方式进步到了多字码加密(Polyalphabetic Cipher)

加密

多字码加密的加密方式就是,在加密之初,加解密双方要先确定一个平移词(shift word)。加密的一方首先需要事先将确定的平移词转变成与其对应的一组数字(称为字码序列),然后对于给定的明文,不断地按照转换后的一组字码序列的长度,循环的对其平移。解密的一方首先也需要将平移词变成其对应的字码序列,然后对于给定的密文,不断地按照转换后的字码序列的长度,循环的对密文字母其进行逆平移。

比如,对于加密条件 明文为 hello,平移词为 hi 的加密过程:

  1. 首先将平移词 hi 变成一组对于的数字,这里按照英文中 26 个字母的出现顺序,平移词 hi 其中的字母换换后所对应的一组数字就是 78(从 0 开始)
  2. 现在需要根据转换后的一组平移数字,逐个循环的对明文进行平移。

     h e l l o
     + + + + + (按照明文字母在 26 个字母中出现的顺序进行平移)
     7 8 7 8 7
     -----------
     o m s t v
  3. 最终,根据上面的变换,就会得出密文 omstv

对于解密的一方,他需要知道平移词 hi,当然这个双方在事先就约定好了。解密方式就不冗述了,就是其加密的逆过程。

破解

相对于凯撒加密的破解过程 - 分析统计密文中的字母频率出现的图表,与明文所采用的语言中字母出现的图表进行简单的平移对比之后,就会得出平移量而言,多字码加密加大了从密文中得出有效的字母出现的频率的难度。但是其解密的原理依旧不复杂。

对于破解者而言,他们更加关心的是多字码加密时采用的字码序列的长度,比如上面的例子中 78 这个字码序列的长度就是 2。另外,之所以在上文的加密的过程的解释中,一直强调 “循环” 这个概念的目的就是,当你理解了 “循环” 的概念之后,你会发现,上面的例子中 h、***个 l、o 都是采用的 7 作为了它们的平移量,那么问题其实又回到了凯撒加密。

于是,对于破解者,他们只要不断地猜测字码的长度,因为明文是按照字码序列的长度循环平移的,一个循环的开头,和下一个循环的开始必定是使用的同样的平移量,只要按照这个规律,将以一个猜测的字码序列的长度为间隔的加密字母挑出来进行频率分析统计,然后与明文的字母频率进行对比,就能得出平移量了 - 回到了凯撒加密的破解过程。

一次一密

19世纪末期,出现了一个具有相当强度的加密方式,称为一次一密(one-time pad)。

加密

所谓一次一密,其加密的字码的长度不再像是上文提到的固定长度了,它所采用的是使用随机的方式得到一个与明文字母等长的随机字码序列。

首先要知道的是,对于英文字母而言,每一个字母所能进行的平移量只有 26 种。因为对于任何一个具有固定长度的计数系统而言(其实就是一个模系统),超过了其模的平移将会从头开始进行移动(补数),这里你可以想象成一个有 26 个小时刻度的时钟,从 0 点顺时针的平移量如果是 27 的话,实际的结果就是 1 点 - 和顺时针直接平移 1 没有什么区别。

那么,对于明文为 hello 的一次一密的加密过程可以是这样:

  1. 随机得到一个 0~25 以内的随机数,假设本次随机数是 3

    1. 记录这个随机数
    2. 将明文 h 平移 3 变成 k
  2. 随机得到一个 0~25 以内的随机数,假设本次随机数是 5

    1. 记录这个随机数
    2. 将明文 e 平移 5 变成 j
  3. 依次类推...

那么假设随机的字码序列是 35685,其对应的密文就是 kjrtt。
如果再次加密的话,需要再次随机生成一个与明文等长的字码序列。

当然,接收方需要同时知道每一次的随机字码序列和对应密文。

破解

对于采用一次一密的加密方式等到的密文,破解者需要面对两个问题:

  1. 用于加密的字码序列的长度是和明文等长的,于是也就没有了 “多字码加密” 中的 “循环” 问题了。
  2. 密文中的每一个字母的出现频率将会是相同的,因为每个明文字母都随机对应到了 26 个字母中的一个,它们出现的概率是相同的。

由于密文没有规律可循,破解者只有通过暴力破解的方式去尝试得出明文。不过,对于明文 hello 它的密文将会是 26*26*26*26*26 = 11881376 种组合中的一种,而且这仅仅是只有 5 个字母的情况。

***保密

理解这样一个游戏:Eve 邀请 Bob 来到一个房间,Bob 发现这个房间除了有一副牌、几把锁(带钥匙的锁和密码锁)、一个空格子之外,什么也没有。Eve 让 Bob 选择一张牌,然后尽他***的能力去将牌藏起来。规则很简单,Bob 不能从房间带走任何物品,所有牌和钥匙必须留在房间内,并且在空格子中最多只可以放一张牌,Eve 保证他没有动过那些锁。如果 Eve 不能找出 Bob 藏的牌的话,Bob 就赢了。那么 Bob 应该怎么做?

首先 Bob 选择了一张方块6,并将它扔进了空盒子中,然后他开始考虑使用哪一个锁将盒子锁起来。似乎使用密码锁是一个很好的选择,不过 Bob 很快意识到一个问题 - 桌上剩余的牌会暴露他的选择。锁只不过是一个陷阱,他不能将牌从牌堆里面拿出来,所以他将选择的牌重新放回牌堆,并将牌堆进行重新的洗牌,以此打乱它们原有的顺序。现在,Bob 选择的牌,可能是牌堆中的任意一张了,他可以信心十足的离开房间。

***,Bob 赢得了游戏,因为 Eve 最多只能靠猜测才能得知 Bob 选择的牌 - Bob 没有留下任何关于其选择的牌的信息。即使给了 Eve 一个没有性能限制的计算机,他也只能靠猜,这就是我们所说的 “***保密” 。

在 1945 年九月一日,29岁的 Claude Shannon 发布了一个保密论文,***次从数学角度去证明 “一次一密” 如何以及为什么具有***的保密性。Claude Shannon 是按照下面的方式去思考加密方案的:

  • 设想 Alice 给 Bob 写了一个 20 个字母长度的消息。这就好比从消息空间(message space)中抽出一个特定页面。对于消息空间,可以想象成是包含 20 个字母可以组成的所有组合的一个集合。

  • 接着 Alice 需要在 0~25 之间随机的生成 20 个字母的密匙(字码)。密匙空间(key space)就是包含所有随机组合情况的一个集合,所以生成一个密匙就好比从密匙空间中随机的抽出一页。

  • 接着 Alice 将密匙的作为一个个平移量应用到明文消息中,得出了密文。密文空间(ciphertext space)表示了所有可能的加密结果组合的集合。当她选择并应用了某一个密匙,结果将会唯一地对应到密文空间中的一页。

  • 注意这里的消息空间大小、等于密匙空间的大小、等于密文空间的大小,这些就是 “***保密” 的定义。所以当只知道密文的情况下,唯一可以得到的信息就是:这段密文唯一对应于消息密文中的一页。因为要破解只能靠猜测,所以无论功能多强劲的计算机,面对只能靠猜测的算法,除了可以缩短猜测的时间之外,并没有什么提升。

现在,在使用一次一密的情况下,唯一需要面对的问题就是,我们如何在事先共享那些长的密匙。

伪随机数生成器

当我们在观察自然界时,我们到处会发现一些随机的波动。我们可以通过对熟知的比如噪音的波动,去测量并生成真实的随机数。当我们在对噪音进行取样的时候,我们可以获得数字。比如,我们通过测量一段时间的电视机电流,我们就可以生成一个真的随机数序列。为了将一个数的序列可视化,我们可以根据序列中的每一个数去画出它们的更改路径,这种方式也叫做随机游走(random walk)。根据可视化后的图像得出,在真随机序列中的任意一点上,都无法预测下一点将会出现在哪里。随机的过程按理说应该是具有非确定性的,因为它们无法事先就测定。

另一方面,机器是具有确定性的,它的操作是可预测的以及可重复的。由于随机数需要被不断以及快速的得到,加上之前的计算机具有有限的存储大小,所以直接存储一个固定长度的随机数是不现实的。所以,在早期的计算机中,科学家发明了一个算法去机械的模拟随机中的乱序现象。这个算法叫做 平方取中 Middle-square method

比如,要使用此算法去生成一个 4 位的伪随机数,就需要先选择一个四位数作为整个过程的起始值(种子),将这个四位数和自身相乘(平方)运算后,会得到一个 8 位的数字(如果不足八位,就在前面补上 0,以凑足 8 位)。得到结果的 8 位数字之后,取出其中的 4 为数字作为结果,或者作为下一次运算的种子,再配合重复上面的过程以获得更多的 4 位伪随机数。

为此方法提供随机性的唯一保障就是最初选择的随机种子。相同的种子,将会生成相同的序列。那么,随机序列和伪随机序列之间有什么不同?可以通过上述提到的随机游走的方式将伪随机序列进行可视化,以此具象化地进行观察。结果就会发现,如果中间产生了一个曾经使用过的种子,那么接下来的结果都将会和之前出现的中间结果发生重复。在伪随机数序列发生重复之前的时期,就被称为周期(the period)。这个周期会被最初选择的种子长度严格限制。比如,我们使用了一个 2 个数字的种子,那么在结果序列发生重复前,可以产生 100 个 2 位数字组合,一旦其中出现了和最初的 2 个数字的种子一样的中间结果,那么接下来的中间结果将会做周期性的重复。3 位数字的种子,就可以产生 1000 个 3 位数字的组合。4 位数字的种子,就可以产生 10000 个 4 位数字的组合。如果我们使用了一个具有非常长长度的种子,那么就可以产生具有非常长周期的伪随机的结果序列。

另外一个需要面对的问题就是,一旦我们选择了伪随机的方式生产随机数,那么就会丢失很多在真随机序列中应该出现的序列。比如,Alice 需要为 20 个字母长度的明文生成一个真随机 20 个字码的组合,那么这些随机字码的组合就有 26^20 次方的可能性,
这将会是一个天文数字。作为对比,假设 Alice 使用的是上面提到的伪随机方式,并使用了一个 4 位的种子。也就是说,使用伪随机的方式,她只能选择 10000 种可能的种子,因此只能生成 10000 种不同的数字序列,我们可以在生成的序列中选择前 20 个作为字码。可以发现,使用了伪随机方式的结果,使得我们的密匙空间被大大的缩小了,密匙空间的太小变成了种子空间(seed space)的大小。

那么作为这种伪随机的破解方式,可以通过不断的猜测所有的可能的种子。这就将问题带到了一个计算机中常见的问题,什么是可能的,以及什么是在一定时间内可能的。在我们买一个自行车密码锁时,其实采用了相同的逻辑。我们知道所有人都可以对密码锁去尝试所有可能数字组合,直到他们找出匹配的那一组并打开了锁。但是,这个过程将花费他们几天的时间,所以对于 8 个小时之内的时间,我们可以认为锁几乎是安全的。在上述伪随机生成方法下,保密程度将随着种子的长度而提高,如果***劲的计算机都需要花几百年才可以尝试掉所有的种子的可能性的话,我们就可以认为这种方式几乎是安全的,但不是***保密。随着计算机的不断发展,种子的长度也需要相应地不断地增长。

采用上述的伪随机方式,使得 Alice 和 Bob 不必事先共享一整个很长的字码序列了。他们只要分享一个对应的随机种子,然后使用那个种子去生成看起来是随机的序列作为字码序列。但是,当他们无法面对面分享那个随机种子时,将会发生什么?

责任编辑:倪明 来源: 简书
相关推荐

2020-04-27 14:18:40

光学信息加密

2009-07-09 09:52:12

PBE加密

2015-05-13 13:13:34

2013-08-30 10:20:47

2012-02-14 10:13:26

2012-12-26 13:45:45

2010-09-17 20:04:21

2009-03-11 11:32:10

JavaJava安全加密技术

2022-05-09 16:01:01

加密货币Web3区块链

2011-05-19 13:45:38

2011-07-08 11:25:31

2012-10-26 09:41:01

透明加密软件多模加密加密

2021-11-29 08:00:00

安全加密技术数据安全

2021-05-21 15:47:03

区块链加密货币技术

2021-02-25 13:43:24

加密货币金融数字货币

2009-12-31 09:57:43

2010-10-12 11:10:49

2012-04-13 13:58:52

数据加密

2018-11-07 10:25:50

2011-12-19 09:46:31

点赞
收藏

51CTO技术栈公众号