热身问答
- 通常把还原加密过的文件这一操作叫作什么?
- 解码
- 解密
- 在字母 A 的字符编码上加上 3,可以得到哪个字母?
- D
- 因为字母表中的字母编码是按字母顺序排列的,所以在字母 A 的编码上加 3,即 A → B → C → D,所以可以得到 D。
- 在数字签名中使用的信息摘要是什么?
- 信息摘要是指从作为数字签名对象的文件整体中计算出的数值
- 对比由文件整体计算出的信息摘要,可以证明文件的内容有没有被篡改。加密处理过的信息摘要就是数字签名。
本节将使用VBScript语言实际编写几个加密程序来体验加密程序的运作。
10.1 什么是加密
我们知道计算机内所有的文本、图像等所有数据都是用数字表示的, 所以加密也就是对数字的加密。
现在我们假设我们的加密对象是文本数据。
那么文本数据是由字符构成的, 而每个字符都被分配了一个数字, 就是“字符编码”。定义了应该把哪个编码分配给哪个字符的字符编码体系叫作字符集。字符集分为 ASCII 字符集、JIS 字符集、Shift-JIS 字符集,EUC 字符集、Unicode 字符集等若干种。
下图中展示了从A到Z的ASCII编码, 计算机在处理文本数据时会处理成数字序列, 然后将数组序列转换为对应的字符显示在屏幕上,就可以实现计算机和我们的沟通了。
比如, NIKKEI会被计算机处理为:“78 73 75 75 69 73”, 还可以将这串数字转换为字符“NIKKEI”。 通常把这种未经加密的文本数据称为“明文”。
当然明文是不安全的, 有被盗用的风险, 所以我们要将其转换为密文。密文也是一串数字, 但是将密文转换为字符之后, 我们很难看懂。
虽然存在各种各样的加密技术,但是其中的基本手段无外乎还是字符编码的变换,即将构成明文的每个字符的编码分别变换成其他的数值。通过反转这种变换过程,加密后的文本数据就可以还原。通常把密文还原成明文的过程(即解读密码的过程)称为“解密”。
10.2 错开字符编码的加密方式
我们来通过运行程序来实际体验加密的过程。
加密:
下面列出了一段用于加密的示例程序
该程序中使用了如下的加密方法:将文本数据中每个字符所对应的字符编码一律向后错三个,即给原字符编码的值加上 3。(上文提到的字符编码的变换)
plaintext = InputBox("请输入明文: ")
cipher = ""
For i = 1 To Len(plaintext)
letter = Mid(plaintext, i, 1)
cipher = cipher & Chr(Asc(letter) + 3)
Next
MsgBox cipher
将这段代码保存为扩展名为.vbs的文件, 双击即可运行。
解密:
因为加密时使用的是将字符编码向后错三个的方法,所以只要再将字符编码向前挪三个就可以实现解密。
下面是解密程序: 与进行加密的程序相反,解密使用的是从字符编码中减去 3 的方法。
cipher = InputBox("请输入密文:")
plaintext = ""
For i=1 to Len(cipher)
letter = Mid(cipher, i, 1)
plaintext = plaintext & Chr(Asc(letter) - 3)
Next
MsgBox plaintext
也就是说,加上 3 就是加密,减去 3 就是解密。因此通常把像 3这样用于加密和解密的数字称为“密钥”。如果事先就把 3 这个密钥作为只有数据的发送者和接受者才知道的秘密,那么不知道这个密钥的人,就无法对加密过的数据进行解密。
下面我们更进一步, 将密钥的值可以由用户指定。
该 程 序 通 过 把 每 一 个 字 符 的 编 码 与 密 钥 做 XOR 运 算(eXclusive OR,逻辑异或运算),将明文转换成密文。用 XOR 运算加密后的密文,可以通过相同的 XOR 运算解密。也就是说,一个程序既可用于加密又可用于解密,很方便。
k = InputBox("请输入密钥: ")
key = CInt(k)
text1 = InputBox("请输入明文或密文: ")
text2 = ""
For i = 1 To Len(text1)
letter = Mid(text1, i, 1)
text2 = text2 & Chr(Asc(letter) Xor key)
Next
MsgBox text2
XOR运算:异或运算的法则也可以描述成如果对应位置上的两个二进制数 a、b 的值相同,则结果为 0。如果 a、b 的值不相同,则结果为 1
XOR 运算的法则是把两个数据先分别用二进制表示,然后当一个数据中的某一位与另一个数据中的 1 相对时,就将这一位反转(若这一位是 0 就变成 1,是 1 就变成 0)A。因为是靠翻转数字实现的加密,所以只要再翻转一次就可以解密。下图中展示了密钥 3(用二进制表示是 00000011)和字母 N(其字符编码用二进制表示是 01001110)做XOR 运算的结果,请诸位确认通过翻转和再翻转还原出字母 N 的过程:N 的字符编码先和 3 做 XOR 运算,结果是字母 M 的字符编码。M 的字符编码再和 3 做 XOR 运算,结果就又回到了 N 的字符编码。
10.3 密钥越长,解密越困难
一些人会利用计算机的强大的计算能力, 输入密钥的可能值去解密。
例如,要想破解用XOR 运算加密得到的密文 MJHHFJ,程序只要把 0 到 9 这几个值分别作为密钥都尝试一遍就能做到
cipher = InputBox(" 请输入密文。")
plaintext = ""
For key = 0 To 9
plaintext = plaintext & " 密钥 " & CStr(key) & ":"
For i = 1 To Len(cipher)
letter = Mid(cipher, i, 1)
plaintext = plaintext & Chr(Asc(letter) Xor key)
Next
plaintext = plaintext & Chr(&HD)
Next
MsgBox plaintext
所以, 我们要将加密程序尽量复杂。 这里我们可以把密钥设为多位数。
下面,我们就丢弃一位数的 3,试着以三位数的 345为密钥,通过 XOR 运算来试着进行加密。将明文中的第一个字母与 3 做 XOR 运算、第二个字母与 4 做 XOR 运算、第三个字母与 5 做 XOR 运算。从第四个字母开始,还是以三个字母为一组依次与 3、4、5 做 XOR 运算,依此类推
Dim key(2)
key(0) = 3
key(1) = 4
key(2) = 5
text1 = InputBox("请输入明文或密文:")
text2 = ""
For i = 1 To Len(text1)
letter = Mid(text1, i, 1)
text2 = text2 & Chr(Asc(letter) Xor key( (i-1) Mod 3))
Next
MsgBox text2
如果仅用一位数作为密钥,那么只需要从 0 到 9 尝试十次就能破解密文。但是如果是用三位数的密钥,那么就有从 000 到 999 的 1000种可能。如果更进一步把密钥的位数增长到十位,结果会怎样呢?那样的话,破解者就需要尝试 10 的 10 次方 = 100 亿次。就算使用了一秒钟可以进行 100 万次尝试的计算机,破解密文也还是需要花费 100 亿 ÷ 100 万次 / 秒 = 10000 秒 ≈ 2.78 小时,密钥每增长一位,破解所花费的时间就会翻 10 倍。密钥再进一步增长到 16 位的话,破解时间就是 2.78 小时 ×1000000 ≈ 317 年,从所需的时间上来看,可以说破解是不可能的。
10.4 适用于互联网的公开密钥加密技术
前面所讲的加密技术都属于”对称密钥加密技术“, 也是”秘密密钥加密基础“。
这种加密技术的特征是在加密和解密的过程中使用数值相同的密钥。
因为加密解密都需要使用同样的密钥, 所以我们需要让发送者和接收者都知道密钥, 而且要隐秘地告诉他们。 发送者本身就拥有密钥, 但是如何让发送者秘密且高效地将密钥告知接收者呢? 这在互联网中很难实现。
但是,我们可以通过“公开密钥加密技术”实现让解密时的密钥不同于加密时的密钥, 就克服了对称密钥加密技术的缺点。
在公开密钥加密技术中,用于加密的密钥可以公开给全世界,因此称为“公钥”,而用于解密的密钥是只有自己才知道的秘密,因此称为“私钥”。
用于实现公开密钥加密技术的算法有许多, 目前应用比较广泛的有RSA算法:
- RSA 这个名字是由三位发明者Ronald Rivest、Adi Shamir 和 Leonard Adleman 姓氏的首字母拼在一起组成的。
- 无论是公钥还是私钥都包含着两个数值,两个数值组成的数对儿才是一个完整的密钥。
看似我们可以通过公钥 c = 323、e = 11 推算出私钥 c = 323,f = 131 了。但是为了求解私钥中的 f,就不得不对 c 进行因子分解,分解为两个素数 a、b。实际情况中 , c的位数会非常大(有可能扩充为1024位), 而这样的数字分解为两个素数是非常耗费时间的。
10.5 数字签名可以证明数据的发送者是谁
工卡密钥加密技术的实际应用: 数字签名 Digital Signature
数字签名可以证明数据的发送者的身份。
如何生成数字签名?
【文本数据的发送者】
(1)选取一段明文
例:NIKKEI
(2)计算出明文内容的信息摘要
例:(78+73+75+75+69+73)÷100 的余数 = 43
(3)用私钥对计算出的信息摘要进行加密
例:43 → 66(字母 B 的编码)
(4)把步骤(3)得出的值附加到明文后面再发送给接收者
例:NIKKEIB
【文本数据的接收者】
(1)用发送者的公钥对信息摘要进行解密
例:B = 66 → 43
(2)计算出明文部分的信息摘要
例:(78+73+75+75+69+73)÷100 的余数 = 43
(3)比较在步骤(1)和(2)中求得的值,二者相同则证明接收的
信息有效
例:因为两边都是 43,所以信息有效
上面的信息摘要/Message Digest可以理解为就是一个数值,通过对构成明文的所有字符的编码进行某种运算就能得出该数值。
注意! 这里使用私钥进行加密, 公钥进行解密, 与之前的用法刚好相反。
本例中信息摘要的算法是把明文中所有字母的编码加起来,然后取总和的最后两位。而在实际中计算数字签名时,使用的是通过更加复杂的公式计算得出的、被称作 MD5(Message Digest5)的信息摘要。由于 MD5 经过了精心的设计,所以使得两段明文即使只有略微的差异,计算后也能得出不同的信息摘要。
发送者用构成文件的所有字符的编码生成了信息摘要,就证明发送者从头到尾检查了文件并承认其内容完整有效。如果接收者重新算出的信息摘要和经过发送者加密的信息摘要匹配,就证明文件在传输过程中没有被篡改,并且的确是发送者本人发送的。正因为数据是用发送者的私钥加密的,接收者才能用发送者的公钥进行解密。
总结
本章主要讲解的是如何对文件进行加密解密, 以及在加密解密的过程中必不可少的技术或者数据有哪些。
明文: 未经加密的文本数据
密文: 加密后的文本数据
加密: 加密技术都基于字符编码的转换, 将构成明文的每个字符的编码分别变换成其他的数值, 实现从明文到密文的变换过程。
解密: 将密文还原成明文的过程
密钥: 用于加密和解密的数字, 此数字是发送者和接收者才知道的秘密。 且密钥越长, 保密性越高。
对称密钥加密技术: 在加密和解密的过程中使用数值相同的密钥。
公开密钥加密技术: 实现解密时的密钥不同于加密时的密钥。
- 公钥: 用于加密的密钥, 可以公开。
- 私钥: 用于解密的密钥, 不可以公开。
数字签名: 用来证明数据的发送者的身份。
- 信息摘要 Message Digest: 通过对明文的所有字符的编码进行某种复杂公式的运算得到的数值。