网站首页 (Homepage) 欢   迎   访   问  谢  国  芳 (Roy  Xie) 的  个  人  主  页
Welcome to Roy Xie's Homepage
返回 (Return)

 

如何独立自主地编制密码 (1)

—— A Guide to Do-It-Yourslef Encryption and Decryption 

      谢国芳(Roy Xie)                               Email:  roixie@163.com   

章节目录

1. 现代密码学发凡

  1.1 编码——把原始资料转化成明码数字流

  1.2 加密和解密的一般原理——明码数字流和密码数字流的相互转换

2. 最简单的不可破译的加密方法——谢国芳加法密码

 

1.  现代密码学发凡 [1]

一个完整的现代密码操作流程分为四步:

(一)编码——把原始资料 O  转化成明码数字流 M

(二)加密——把明码数字流 转化成密码数字流 M'

(三)解密——把密码数字流 M'  还原成明码数字流 M ,这是第二步加密的逆操作。 

(四)译码——把明码数字流 还原成原始资料 O ,这是第一步编码的逆操作。

其中的核心步骤自然是加密和解密,但它们必须以第一步——编码为基础,所以我们先从这最基础也最容易的第一步——编码开始谈起。

 

1.1  编码——把原始资料转化成明码数字流

在计算机的世界中,诚如古希腊数学家毕达哥拉斯所言,“万物皆数”,任何资料,无论是文本、还是图像、视频,归根结底都是二进制文件,即由 0 和 1 组成的一串数字。

套用《爱丽丝梦游仙境》中的小爱丽丝的一句经典的台词, "You're nothing but a pack of cards!"(你们只不过是一堆扑克牌!),我们可以说,“Everything in the computer is nothing but a string of numbers!"

把文字、图像等各种资料转化成数字的过程就是编码(encoding)。

以文字为例,把文本数字化最简单方法的是赋予每个字符(即构成文字的基本单位,例如西方语言中的字母,中文中的汉字)一个特定的数字,你可以采用各种现成的代码,例如英文的ASCII码,中文的区位码,和几乎涵盖地球上所有文字的“万国码”Unicode。当然,倘若你有雅兴,也可以用你自己独特的方式进行原创式的编码。以中文为例,你可以给每个汉字指定一个只有你知道的数字(它就是你赋予该汉字的私密代码),选择什么样的数字完全是任意的,只有一个约束条件:你必须保证汉字和数字之间是一一对应的。在成功地创造了一套代码体系——即建立了所有字符和某个数集之间的一一对应关系后,你可以把它存在一个电脑文件(比如 Excel 文件)或记在一个本子上,这就是你的私密代码本,每当需要编码或译码的时候可以随时调用(更好的办法是编一个程序自动干这件事)

无论你是采用标准的代码还是独家原创的私密代码,总之,经过编码后你的原始资料 O(比如说一个文本)就转化成了一串数字,我们可以称之为“明码数字流” ,假设它一共包含 N 个数字,用 M 表示第 i 个数字,明码数字流 就是一个有限的数列:

M1 , M2 , M3 , M4 , ......, MN

为了方便,通常都选取 M 为正整数。

→ 编码的具体实例参见 例1

 

1.2  加密和解密的一般原理——明码数字流和密码数字流的相互转换

选择一个定义在明码数字流 M  ={ M1, M2, M3, M4, ......, MN } 上的可逆函数 f ,计算每个 M f 作用下的值 f ( M) ,用 M'  记之,即

              M'  = f ( M )        ( i = 1, 2, 3, ......, N )

完成对所有 M 的计算后,我们就得到了加密后的数字流即“密码数字流”

M'  =  { M1',  M2',  M3',   M4',   ...... ,  MN ' }

我们可以把函数 f 称为“加密函数”(encryption function).

为了解密,即把密码数字流还原成明码数字流,只需求出加密函数的逆函数 f -1,将它逐个作用在密码数字流 M' 上,我们就重新得到了明码数字流 M ,因为

                                  f -1 (  M' )   =   f -1 f (  M ) )  =   M        ( i = 1, 2, 3, ......, N )

最后,根据你的编码,即可将明码数字流 M 还原成原始资料

最简单的加密函数是 f (x)  =  x + K   ,其中 K  是一个常数, 这样的加密方法可以称为“加法加密法”,由此产生的密码可以称为“加法密码”,常数 K 就是你的密钥(key)。

类似地,我们也可以用乘法来加密,即选择加密函数 f (x)  =   K x ,其中 K  是一个常数,这可以称为“乘法加密法”,相应的密码可以称为“乘法密码”。

更一般地,我们可以考虑“加法密码”和“乘法密码”的叠加,即选取加密函数为一般的一次函数或者说线性函数 f (x)  =  ax + b  ,其中a, b个常数, 这样的加密机制可以称为“线性加密法”,由此产生的密码可以称为“线性密码”它的另一个更专业一点的名称是“仿射密码”(这听上去有点唬人,还是叫“线性密码”更平易近人一些)

例1  用加法密码法加密信息:“明晚八点钟老地方碰头”。

Step 1. 编码 

加密任何信息的第一步是编码,即将它转换成数字。假设我们采用汉字区位码对原始信息

= 明晚八点钟老地方碰头

进行编码,查得上面各汉字的区位码如下(可以在网上查询汉字区位码):

明 3587   晚 4577   八 1643   点 2167   钟 5451   老 3247   地 2156   方 2329   碰 3786   头 4523 

我们于是就将原始信息 转化成下面的明码数字流:

                      =   3587, 4577, 1643, 2167, 5451, 3247, 2156, 2329, 3786, 4523                      (1)

Step 2. 加密 

选择加密函数 f (x)  =  x + K K 的取值是任意的,比方说  K   = 1285在实际操作中,你需要对该数值保密,它相当于是你的加密密钥,同时也是解密密钥),即把(1)中的每个数字加上1285,就生成了加密后的数字流即密码数字流:

                      M'  4872, 5862, 2928, 3452, 6736, 4532, 3441, 3614, 5071, 5808                      (2)

倘若用汉字区位码进行译码(即逐个查出区位码等于上面各数字的汉字),它是无人能识的密文:

O'  = 需谵郊略隳屠律漠溢讪

 

Step 3. 解密 

加密函数 f (x)  =  x + 1285  的逆函数是  f -1 ( x )   =  x - 1285  ,将它逐个作用在密码数字流上,即(2)中的每个数字减去1285,就再现了明码数字流:

=   3587, 4577, 1643, 2167, 5451, 3247, 2156, 2329, 3786, 4523

最后倒查汉字区位码(已知区位码查汉字),就看到了原始消息即明文:

= 明晚八点钟老地方碰头

 

 

2.  最简单的不可破译的加密方法——谢国芳加法密码

 上一节中的例1只是为了阐明加法加密法的原理而举的一个例子,在实际应用中,它存在下面这两个缺陷(想必你也已经想到了)

1. 我们选择的密钥 K  只是一个四位数,容易被猜到或者用穷举搜索法(即试遍从1到9999的所有数字)破解。

2. 这种简单的加法密码法相当于把每个汉字的区位码向后(或向前)移动了一个相同的数,这好比是把所有的鸡蛋都放在同一个篮子里——只要一个字被破译,整个密码就被破译了。例如,只要知道汉字“八”(区位码1643) 对应的密文是“郊”(区位码2928), 就马上可以算出密钥 K  =  2928 - 1643  =  1285,从而一举破译所有其他汉字。

针对这两个缺陷,我们可以作如下这两方面的改进,从而大大提高密码的保密度或者说破译难度:

1. 加长密钥的长度,比如说把它增加到十位、二十位,甚至一百位、一千位。

2. 把明码数字流的数字合并重组,合并重组的方式完全是任意的(这本身就又是一重加密),作为最极端的情形,我们可以把所有数字合并成一个数字。

一般选取密钥的长度和合并重组后明码数字流的数字位数相等。

下面称作了这样改进的加法加密法为“谢国芳加法加密法”(因为它是作者本人首创),相应的密码称为“谢国芳加法密码”,这可以说是一种最简单的不可破译的密码。

我们先看一个具体的例子。

例2  用谢国芳加法密码加密信息:“明晚八点钟老地方碰头”。

Step 1. 编码 

仍采用汉字区位码对原始信息

 O  = 明晚八点钟老地方碰头

进行编码,查得各汉字的区位码如下可以在网上查询汉字区位码):

明 3587   晚 4577   八 1643   点 2167   钟 5451   老 3247   地 2156   方 2329   碰 3786   头 4523 

将它们合并,得到一个四十位数字的明码数字流:

=   3587457716432167545132472156232937864523

Step 2. 加密 

既然明码数字流是一个四十位的数字,我们接下来要选择的密钥 K, 即加密函数 f (x)  =  x + K 中的常数 K 也应该是四十位数,怎样选取一个如此长且又好记的密钥呢?一个最简单的方法是随便想一句话,然后通过编码将它转化成数字来充当你的密钥。比方说,你可以选取产生密钥的语句为

“我用了谢国芳加法密码”

查出各汉字的区位码:

我 4650   用 5135   了 3343   谢 4827   国 2590   芳 2328   加 2851   法 2308   密 3560   码 3475

由此便得到一个四十位数的密钥

                      K   =   4650513533434827259023282851230835603475               (3)

密钥 K  和明码数字流 相加,就生成了加密后的数字流即密码数字流:

                      M'  =  8237971249866994804155755007463773467998        (4)

Step 3. 解密 

将加密函数 f (x)  =  x + K  的逆函数  f -1 ( x )   =  x -  K  作用在密码数字流上,即(4)减去(3),就再现了明码数字流:

=   3587457716432167545132472156232937864523

最后重新将它分割为每四个数字一组用汉字区位码进行译码,就看到了原始消息即明文:

= 明晚八点钟老地方碰头

 

 

  To be continued(à suivre

 

 注 解

[注1] 本文的思想和理论体系以及许多术语如“明码数字流”“密码数字流”等均为独家原创,引用者请务必注明出处。