如果您是初学者,Python 是最好的入门语言,这正是它如此流行的原因。您只需几行就可以编写功能强大的代码,最重要的是,您可以完全精确地处理任意大的整数。这本书涵盖了基本的密码学概念;经典的加密方法,如凯撒密码和异或;混淆和扩散的概念决定了密码系统的强度;通过模糊处理隐藏数据;散列数据的完整性和密码;以及强加密方法和针对这些方法的攻击,包括填充 oracle 攻击。您不需要有编程经验就可以了解这些。你不需要任何特殊的计算机;任何可以运行 Python 的计算机都可以执行这些项目。我们不会仅仅为了学习如何使用标准的、已经存在的加密技术而发明新的加密技术,这些加密技术只需要非常基本的代数。
我们将首先讨论模糊处理,即什么是加密的基本概念,以及隐藏数据使其更难读取的老式加密技术。后一个过程是加密模块与其他方法结合使用的基本活动之一,以使加密技术更强大、更现代。
在本章中,我们将介绍以下主题:
- 关于密码学
- 安装和设置 Python
- 凯撒密码与 ROT13
- base64 编码
- 异或
随着比特币、以太坊和 Litecoin 等所有货币的引入,加密一词最近已经超载。当我们将加密称为一种保护形式时,我们指的是应用于系统中使用的通信链路、存储设备、软件和消息的加密概念。密码学在保护关键系统和敏感信息方面有着悠久而重要的历史。
在第二次世界大战期间,德国人使用 Enigma 机器对通信进行加密,盟国竭尽全力破解加密。Enigma 机器使用一系列转子将明文转换为密文,通过了解转子的位置,盟军能够将密文解密为明文。这是一项重大成就,但需要大量人力和资源。今天,破解某些加密技术仍然是可能的;然而,攻击密码系统的其他方面,例如协议、集成点,甚至用于实现密码的库,通常更为可行。
密码学有着丰富的历史;然而,如今,你会遇到一些新的概念,比如区块链,它们可以用作帮助物联网安全的工具。区块链基于一组众所周知的加密原语。密码学中的其他新方向包括量子抵抗算法,它可以抵抗量子计算机和量子密钥分发的理论冲击。他们使用诸如 BB84 和 BB92 之类的协议来利用量子纠缠的概念,并为使用经典加密算法创建高质量密钥。
Python 的安装从来都不容易。为了继续,让我们确保已经在机器上设置了 Python。我们将了解如何在 macOS 或 Linux 上使用 Python,以及如何在 Windows 上安装 Python。
在 macOS 或 Linux 系统上,您不需要安装 Python,因为它已经包含在内。您只需打开一个终端窗口并输入python
命令。这将使您进入交互模式,您可以逐个执行python
命令。您可以通过执行exit()
命令来关闭交互模式。因此,基本上,为了创建脚本,我们使用nano
文本编辑器,后跟文件名。然后输入python
命令并保存文件。然后,您可以使用python
后跟脚本名来运行脚本。因此,让我们通过以下步骤了解如何在 macOS 或 Linux 上使用 Python:
- 在 macOS 或 Linux 系统上打开终端并运行
python
命令。这将打开 Python 的交互模式,如以下屏幕截图所示:
- 当您使用
print
命令时,它会立即打印Hello
:
>>> print "Hello"
Hello
- 然后,我们将使用以下命令离开:
>>> exit()
- 如前所述,要在交互模式下使用 Python,我们将输入如下命令:
$ nano hello.py
- 在
hello.py
文件中,我们可以编写如下命令:
print "HELLO"
- 仅当您已修改文件时,按Ctrl+X,然后按Y和Enter保存文件。
- 现在,让我们键入 Python,后跟脚本名称:
$ python hello.py
运行时,您将获得以下输出:
前面的命令运行脚本并打印出HELLO
;如果你有 macOS 或 Linux 系统,这就是你所要做的。
如果你有 Windows,你必须下载并安装 Python。
以下是您需要遵循的步骤:
- 从下载 Pythonhttps://www.python.org/downloads/
- 在命令提示窗口中运行它
- 使用 Python 启动交互模式
- 以
exit()
结束
要创建脚本,只需使用记事本,输入文本,用Ctrl+S保存文件,然后用python
后跟脚本名称运行它。让我们开始安装
使用前面给出的链接打开 Python 页面并下载 Python。它为您提供了各种版本的 Python。在本书中,我们将使用 Python 2.7.12。
有时,您无法立即安装它,因为 Windows 将其标记为不受信任:
- 您必须首先在属性中取消阻止它,这样它才能运行,然后运行安装程序
- 如果您完成安装程序的步骤,您将看到一个名为 addpython.exe to path 的可选步骤。您需要选择该选项
该选择的目的是使 Python 可以从终端窗口中的命令行运行,该窗口称为 Windows 上的命令提示符。
现在让我们继续安装:
- 打开终端并键入以下命令:
$ python
- 当您运行它时,您可以看到它工作正常。现在,我们将键入一个命令:
print "HELLO"
请参阅以下屏幕截图:
- 我们可以使用前面显示的
exit()
命令退出。 - 现在,如果要生成脚本,请键入以下命令:
notepad hello.py
- 这将打开记事本:
- 我们要创建一个文件。在该文件中,我们输入以下命令:
print "HELLO"
- 然后,保存并关闭它。为了运行它,我们需要输入以下命令:
$ python hello.py
它运行并打印HELLO
。
通常,当您在 Windows 上安装 Python 时,它无法更正路径,因此您必须执行以下命令来创建符号链接;否则,Python 将无法从命令行正确启动:
**cd c: \Windows**
**mklink /H python.exe**
**c: \python27\python.exe**
在下一节中,我们将介绍凯撒密码和 ROT13 混淆技术。
在本节中,我们将解释什么是凯撒密码以及如何在 Python 中实现它。然后,我们将考虑其他的 T0 值、模运算和 ROT13。
凯撒密码是一种古老的技巧,你只需将字母表中的每个字母向前移动三个字符。以下是一个例子:
- 明文:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
- 密文:
DEFGHIJKLMNOPQRSTUVWXYZABC
所以,HELLO
变成了KHOOR
。
为了实现它,我们将使用string.find()
方法。Python 的交互模式有利于测试新方法,因此很容易创建一个字符串。您可以制作一个非常简单的脚本来实现 Caesar 密码,使用一个名为alpha
的字符串表示字母表。然后您可以从用户处获取输入,这是明文方法,然后设置一个值n
,该值等于字符串的长度,并且字符串 out 等于空字符串。然后我们有一个循环,通过n
重复,从中的字符串中找到字符,然后在alpha
字符串中找到该字符的位置。然后它打印出这三个值,这样我们就可以确保脚本正常工作,然后它将3
添加到loc
(位置)并将相应的字符放入字符串输出,然后再次打印出部分值,这样我们就可以看到脚本正常工作。最后,我们打印最终输出。添加额外的打印语句是开始编程的一个非常好的方法,因为您可以检测错误
让我们继续打开终端,按照以下步骤在 Python 中实现 Caesar 密码:
- 我们将首先在交互模式下使用 Python,然后制作一个只有几个字母的字符串来测试此方法:
>>> str = "ABCDE"
>>> str.find("A")
0
>>> str.find("B")
1
>>> exit()
- 因为我们了解字符串方法的工作原理,所以我们将退出并进入
nano
文本编辑器查看脚本的第一个版本:
$ nano caesar1.py
- 运行该命令时,将获得以下代码:
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
str_in = raw_input("Enter message, like HELLO: ")
n = len(str_in)
str_out = ""
for i in range(n):
c = str_in[i]
loc = alpha.find(c)
print i, c, loc,
newloc = loc + 3
str_out += alpha[newloc]
print newloc, str_out
print "Obfuscated version:", str_out
您可以在脚本中看到字母表和用户的输入。您计算字符串的长度,对于每个字符,C
将是处理时的一个字符,loc
将是该字符的数字位置,newloc
将是loc
加3
,然后我们可以将该字符添加到字符串中。让我们看看这个
- 使用Ctrl+X离开,然后输入以下命令:
$ python caesar1.py
- 运行此命令时,将获得以下输出:
Enter message, like HELLO:
- 如果输入
HELLO
,则打印出KHOOR
的正确答案:
当我们运行这个脚本时,它接受了HELLO
的输入,并将其逐个字符分解,以便在单独的一行中处理每个字符。H
被发现是第 7 个字符,因此添加3
给了我10
,结果是K
。它逐个字符地向我们展示了它的工作原理。因此,该脚本的第一个版本是成功的。
为了进一步清理代码,我们将删除不必要的print
语句并切换到shift
变量。我们将创建一个变量shift
变量。它也来自原始输入,但我们必须将其转换为整数,因为原始输入被解释为text
,因为您不能将text
添加到整数。这是接下来脚本中唯一的变化。如果你给它一个shift
值3
,你会得到KHOOR
;如果给它一个shift
值10
,则得到ROVVY
;但如果您输入一个shift
值14
,它就会崩溃,表示字符串索引超出范围。这里的问题是,我们多次添加到loc
变量,最终,我们移动到Z
之后,该变量不再有效。为了改善这一点,在向变量添加一些内容后,我们将检查它是否大于或等于26
,以及是否可以从中减去26
。运行此命令后,您可以使用14
班次,这将起作用。我们可以使用24
的移位,它也可以工作。然而,如果我们使用44
的移位,它又超出了范围。这是因为在26
结束时只减去26
一次是不够的,正确的解决方案是模运算。如果我们放入% 26
,它会计算出数模26
,这将阻止它离开0
到25
的范围。它将把它除以26
并只保留余数,正如本例中所预期的那样。随着密码学的发展,我们将更多地看到模块化函数。您可以输入您选择的任何shift
值,例如300
,它将永远不会崩溃,但会将其转换为0
和25
之间的数字。
让我们看看脚本如何与其他 shift 值一起工作:
- 看看凯撒的剧本:
$ nano caesar2.py
- 运行时,您将获得以下信息:
- 这个脚本允许我们改变
shift
值,但不处理shift
值变得太大的任何事情。让我们运行以下命令:
$ python caesar2.py
- 如果您输入
HELLO
并给它一个3
的班次,这是可以的,但是如果我们再次运行它并给它一个20
的班次,它会崩溃:
因此,正如预期的那样,这一点存在一些局限性。
- 让我们转到
caesar3
:
$ nano caesar3.py
- 运行后,我们得到以下输出:
Caesar3
试图解决这个问题,如果我们知道加法导致它大于或等于26
并从中减去26
。
- 让我们运行以下命令:
$ python caesar3.py
- 我们会给它
shift
个字符和20
的shift
就可以了:
- 如果我们给它一个
40
的移位,它不工作:
虽然有一些改进,但我们仍然无法处理任何shift
的值。
- 让我们转到
caesar4
:
$ nano caesar4.py
- 运行该命令时,您将得到以下结果:
这是一个使用带百分号的模运算的算法,它不会失败。
- 让我们运行以下命令:
$ python caesar4.py
- 运行该命令时,您将得到以下结果:
这是处理 Caesar shift 的所有值的脚本。
ROT13 不过是一个凯撒密码,其shift
等于13
个字符。在下面的脚本中,我们将把移位硬编码为13
,如果你运行一个 ROT13 循环,它将HELLO
变为URYYB
,如果你用同样的过程再次加密它,放入那个URYYB
,它将变回HELLO
,因为第一个移位只需13
字符,然后再移位另一个13
角色将全部转移到26
,这一点很重要,也很有用:
- 现在让我们使用以下命令查看 ROT13 脚本:
$ nano rot13.py
- 运行上述命令时,可以看到脚本文件:
- 这正好等于我们上次的凯撒密码移位,脚本移位为
13
。按如下所示运行脚本:
$ python rot13.py
以下是输出:
- 如果我们输入消息
URYYB
并运行它,它将返回到HELLO
:
这很重要,因为有相当多的加密函数具有此属性;当您对某个内容加密一次,然后再加密一次时,您将反转该过程。它不是变得更加密,而是变得不加密。在下一节中,我们将介绍 base64 编码。
我们现在将讨论如何将 ASCII 数据编码为字节,以及如何对这些字节进行 base64 编码。我们还将介绍二进制数据的 base64 编码和返回原始输入的解码。
在 ASCII 中,每个字符转换为一个字节:
A
在基数10
中为65
,在二进制中为0b01000001
。在这里,你在最高有效位有0
,因为没有128
,然后在64
和1
的下一位有1
,所以你有64+1=65。- 下一个是带底座
66
的B
和带底座67
的C
。B
的二进制是0b01000010
,而C
的二进制是0b01000011
。
三个字母的字符串ABC
可以解释为如下所示的 24 位字符串:
我们添加了这些蓝线只是为了显示字节在哪里被分解。要将其解释为 base64,需要将其分成 6 位的组。6 位总共有 64 个组合,因此需要 64 个字符对其进行编码。
使用的字符如下:
我们使用大写字母表示前 26 个,小写字母表示另 26 个,数字表示另 10 个,最多 62 个字符。在 base64 最常见的形式中,最后两个字符使用+
和/
:
如果您有一个三个字符的 ASCII 字符串,它将转换为 24 位,解释为 3 组 8。如果你把它们分成 4 组,每组 6 个,你有 4 个介于 0 和 63 之间的数字,在这种情况下,它们会变成Q
、U
、J
和D
。在 Python 中,只有一个字符串后跟以下命令:
>>> "ABC".encode("base64")
'QUJD\n'
这将完成编码。然后在末尾添加一个额外的回车,这既不重要也不影响解码。
如果你有一组 3 字节以外的东西呢?
The =
sign is used to indicate padding if the input string length is not a multiple of 3 bytes.
如果输入有四个字节,那么 base64 编码以两个等号结束,只是为了表示它必须添加两个填充字符。如果有五个字节,则有一个等号,如果有六个字节,则没有等号,这表示输入整齐地适合 base64,而不需要填充。填充为空。
取ABCD
并对其进行编码,然后取ABCD
,显式字节为零。x00
表示一个包含八位零的单个字符,只需一个额外的A
和一个等于,就可以得到相同的结果,如果你一直用两个字节的零来填充它,你就会一直得到大写字母A
。记住:大写字母A
是base64
中的第一个字符。它代表零的六位。
让我们来看一下 Python 中的 Base64 编码:
- 我们将开始
python
并编一条线。如果您只需制作一个带引号的字符串并按Enter,它将以即时模式打印:
>>> "ABC"
'ABC'
- Python 将自动打印每次计算的结果。如果我们用
base64
编码,我们将得到:
>>> "ABC".encode(""base64")
'QUJD\n'
- 它会变成
QUJD
,最后会有额外的勇气返回,如果我们让它变长:
>>> "ABCD".encode("base64")
'QUJDRA==\n'
- 它有两个等号,因为我们从四个字节开始,它必须再加上两个,使之成为三的倍数:
>>> "ABCDE".encode("base64")
'QUJDREU=\n'
>>> "ABCDEF".encode("base64")
'QUJDREVG\n'
- 对于五字节的输入,我们有一个等号;对于六个字节的输入,我们没有更多的等号,相反,我们总共有八个字符与
base64
。 - 让我们用两个等号回到
ABCD
:
>>>"ABCD".encode("base64")
'QUJDRA==\n'
- 通过在此处显式地添加填充,您可以看到填充是如何完成的:
>>> "ABCD\x00\x00".encode("base64")
'QUJDRAA=\n'
第一个字节是零,现在我们得到另一个等号。
- 让我们输入第二个零字节:
>>> "ABCD\x00\x00".encode("base64")
'QUJDRAAA\n'
我们在这里没有填充,我们看到最后的字符都是A
,这表明已经填充了二进制零。
下一个问题是处理二进制数据。可执行文件是二进制文件,而不是 ASCII 文件。此外,图像、电影和许多其他文件都有二进制数据。ASCII 数据总是以零作为第一位开始,但是base64
可以很好地处理二进制数据。这是一个常见的可执行文件,一个法医实用程序;它以MZê
开头,具有不可打印的 ASCII 字符:
由于这是一个十六进制查看器,您可以看到十六进制的原始数据,在右侧,它尝试将其打印为 ASCII。Windows 程序在开始时有这个字符串,并且这个程序不能在 DOS 模式下运行,但是它们有很多不可打印的字符,比如FF
和0
,这对 Python 来说根本不重要。像这样编码数据的一种简单方法是直接从文件中读取。您可以使用with
命令,它只需打开一个文件名为的文件,然后用句柄f
读取二进制文件,然后您就可以读取该文件。with
命令在这里只是告诉 Python 打开该文件,如果由于某些错误而无法打开该文件,然后关闭句柄,然后以完全相同的方式对其进行解码。要解码以这种方式编码的数据,只需获取输出字符串,然后放入.decode
而不是.encode
。
现在让我们来看看如何处理二进制数据:
- 我们将首先退出 Python,以便查看文件系统,然后使用下面显示的命令查找
Ac
文件:
>>> exit()
$ ls Ac*
AccessData Registry Viewer_1.8.3.exe
这是文件名。因为这是一个很长的块,所以我们将复制并粘贴它。
- 现在我们使用以下命令启动 Python 和
clear
屏幕:
$ clear
- 我们将再次开始
python
:
$ python
- 好的,现在我们使用以下命令:
>>> with open("AccessData Registry Viewer_1.8.3.exe", "rb") as f:
... data = f.read()
... print data.encode("base64")
在这里,我们首先输入文件名,然后输入读取二进制文件的模式。我们将给它文件名句柄f
。我们会把所有的数据放在一个变量数据中,我们可以将数据编码到base64
中,它会自动打印出来。如果在 Python 中有一个预期的块,则必须按两次Enter键,以便它知道该块已完成,然后base64
对其进行编码。
- 你会得到一个很长的
base64
块,它不是很可读,但这是一种处理类似数据的简便方法;比如说,如果你想通过电子邮件发送或以其他文本格式发送。因此,为了进行解码,让我们对一些更简单的东西进行编码,这样我们就可以很容易地看到结果:
>>> "ABC".encode("base64")
'QUJD\n'
- 如果我们想使用它,请使用以下命令将其放入一个
c
变量中:
>>> c = "ABC".encode("base64")
>>> print c
QUJD
- 现在我们可以打印
c
以确保我们得到了预期的结果。我们有QUJD
,这是我们所期望的。因此,现在我们可以使用以下命令对其进行解码:
>>> c.decode("base64")
'ABC'
base64
未加密。它没有隐藏任何东西,但它只是表达它的另一种方式。在下一节中,我们将介绍 XOR。
本节解释了在真值表中的单个位上的 XOR 是什么,然后展示了如何在字节上执行 XOR。XOR 会撤消自身,因此解密操作与加密操作相同。您可以对 XOR 使用单字节或多字节键,我们将使用循环来测试键。这是 XOR 真值表:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
如果输入两个位且两个位相同,则答案为0.
如果两个位不同,则答案为1
。
XOR operates on one bit at a time. Python indicates XOR with the ^
operator.
真值表显示了它是如何工作的。你输入同样可能是0
和1
的位,然后将它们异或在一起,最后得到 50%的 1 和 0,这意味着异或不会破坏任何信息。
以下是字节的 XOR:
A 0b01000001
B 0b01000010
XOR 0b00000011
A
是数字65
,所以您有1
表示64
,有1
表示1
;B
比1
大,如果将两者异或在一起,所有的位都匹配前 6 位,它们都是0
。最后两位不同,变成了1
。这是二进制值3
,它不是可打印字符,但您可以将其表示为整数。
密钥可以是单字节或多字节。如果密钥是单个字节,如B
,则使用相同的字节加密每个明文字符。只需反复重复该键:
对这个字节重复B
,对那个字节重复B
,依此类推。如果键为多字节,则重复该模式:
第一个字节使用B
,下一个字节使用C
,下一个字节使用B
,下一个字节使用C
,依此类推
要在 Python 中实现这一点,需要循环遍历字符串的字节,并计算一个索引以显示所使用的字节。然后我们从用户输入一些文本,计算其长度,然后从1
到字符串长度,从0
开始遍历索引。然后我们把文本字节打印出来,这样你就可以看到循环是如何工作的。所以,如果我们给它一个五个字符的纯文本,比如HELLO
,它只会一个接一个地打印出字符。
**要进行异或运算,我们将输入一个明文和一个键,然后取一个字节的文本和一个字节的键,对它们进行异或运算,并打印出结果
注意%len( key)
,这是防止您跑出钥匙末端的原因。它只会不断重复密钥中的字节。因此,如果密钥长度为三个字节,这将是模数三,因此它将计为0
、1
、2
,然后返回到0 1 2 0 1 2
,依此类推。通过这种方式,您可以处理任意长度的明文。
如果将大小写字母组合在一起,通常会发现 XOR 生成无法打印的字节。在下面的示例中,我们使用了HELLO
、Kitty
和qrs
键。请注意,其中一些字节很容易打印,有些字节包含奇怪的字符,如Esc和Tab,这些字符很难打印。因此,处理输出的最佳方法不是尝试将其打印为 ASCII,而是将其打印为hex
编码值。我们不是尝试逐个打印字节,而是将它们组合成cipher
变量,最后,我们打印出整个明文、整个密钥,然后以十六进制打印出整个密文。通过这种方式,它可以正确处理这些难以打印的奇怪值。
让我们在 Python 中尝试这种循环:
- 我们打开终端并输入以下命令:
$ nano xor1.py
- 运行时,您将获得以下输出:
- 这是第一个
xor1.py
,所以我们从用户那里输入文本,计算它的长度,然后一个接一个地打印出字节,看看循环是如何工作的。让我们运行它并给它HELLO
:
- 它只是一个接一个地打印出字节。现在,让我们来看下一个 XOR 2:
以相同的方式输入text
和key
,并遍历text
的每个字节,使用模运算选择key
的正确字节,执行异或运算,并打印结果。
- 因此,如果我们在这里运行同一个文件,则取
HELLO
和key
,如图所示:
$ nano xor2.py
$ python xor2.py
因此,输出如下:
它逐个计算字节。注意,我们在这里是如何得到两个等号的,这就是为什么你会使用key
的倍数,因为明文在变化,但键也在变化,并且该模式没有反映在输出中,所以它是更有效的模糊处理。
- 清除该选项并查看第三个
xor2a.py
文件:
您可以看到,这解决了不可打印字节的问题。
- 因此,我们创建了一个名为
cipher
的变量,在这里组合输出的每个字节,最后,我们用hex
对其进行编码,而不是直接尝试print
将其输出:
- 如果您给它
HELLO
然后文本一个qrs
键,它会给您明文HELLO Kitty
键,然后是十六进制编码输出,可以轻松处理有趣的字符,如0 7
和0 5
。在下一节中,您将看到挑战 1——凯撒密码。
在 Caesar 密码回顾之后,我们将有一个如何解决它的示例,然后是您的挑战。记住凯撒密码是如何工作的。你有一个可用字符的字母表,你接收信息和一个shift
值,然后你只需将字符向前移动字母表中的许多步骤,如果你绕着末尾移动,就可以将其环绕。我们最终得到的脚本适用于任何shift
值,包括正常数字,如3
,甚至大于26
的数字;它们只是环绕,可以扰乱你放入的任何数据。
下面是一个例子:
- 对于密文,您只需尝试从
0
到25
的所有shift
值,就可以对其进行解密,其中一个值就是可读的。这是一个简单的暴力攻击。让我们来看一看。
在这里,在 Python 中,转到我们以前使用过的caesar4
脚本。它接受一个字符串并按您指定的任何值进行移位。如果我们使用该脚本,我们可以按如下方式运行它:
- 然后,如果我们放入
HELLO
并将其移位3
,它将变成KHOOR
。 - 如果我们想破解它,我们可以使用解决方案脚本,如下所示:
- 因此,如果我们使用该脚本,我们可以运行它:
- 如果我们把它放在
KHOOR
中,它会根据不同的值进行移位,你可以在23
中看到一个可读的值,也就是HELLO
。因此,我们前面讨论的较长密文等的示例将在3
处变得可读,您可以看到它的DEMONSTRATION
:
- 你的挑战是破译这个字符串:
MYXQBKDEVKDSYXC
。
在下一节中,我们将对base64
进行挑战。
在base64
回顾之后,我们将执行一个示例,向您展示如何解码一些模糊文本,然后我们有一个简单和一个困难的挑战。
以下是base64
回顾:
base64
编码文本使其更长。下面是要解码的示例文本:
U2FtcGxliHRleHQ=
它解码为字符串示例文本。让我们来看一看。
请参阅以下步骤:
- 如果您以即时模式运行
python
,它将完成四项简单的工作:
$ python
- 所以,如果我们取
ABC
并用base64
编码,我们得到这个字符串:
>>> "ABC".encode("base64")
'QUJD\n'
- 如果我们用
base64
解码,我们回到原始文本:
>>> "QUJD".decode("base64")
'ABC'
- 因此,挑战文本如下所示,如果对其进行解码,将得到字符串示例文本:
>>> "U2FtcGxliHRleHQ=".decode("base64")
'Sample text'
- 所以,对于简单的情况就可以了;您的第一个挑战如下所示:
Decode this: VGhpcyBpcyB0b28gZWFzeQ==
- 下面是一个长字符串,可供您进行更长时间的挑战:
Decode this:
VWtkc2EwbEliSFprVTJeFl6SlZaMWxUUW5OaU1qbDNVSGM5UFFvPQo=
这个长字符串之所以如此之长,是因为base64
不仅对它进行了一次编码,而且对它进行了多次编码。所以,你必须尝试解码它,直到它变成可读的东西。在下一节中,我们将有挑战 3–XOR。
在本节中,我们将回顾 XOR 的工作原理,然后给出一个示例,然后向您介绍两个挑战。
下面是我们之前讨论过的 XOR 程序之一:
您可以输入任意文本和任意键,然后逐个检查字节,选择一个字节的文本和一个字节的键,然后将它们与 XOR 组合并打印出结果。所以,如果你输入HELLO
和qrs
,你会得到加密的东西,用 XOR 加密。
下面是一个例子:
它将爬进EXAMPLE
。因此,这将撤消加密;请记住,XOR 会自行撤销。
如果您想进入其中一个,一个简单的过程就是尝试每个键并打印每个键的结果,然后读取可读的键。
所以,我们尝试了从0
到9
的所有单位数键。
结果是你输入密文,用每一个加密,当你点击正确的键值时,它就会变成可读的文本。
让我们来看一看:
这里是解密例程,它只是从用户输入文本,然后尝试该字符串中的每个密钥,0
到9
。对于它组合的每一个键,将 XORed 文本想象成一个名为clear
的变量,这样它就可以为每个键打印一行,然后输出清晰的结果。所以,如果我们运行这个程序并输入我的密文,它会给我们 10 行
我们刚刚扫描了这些行,看到哪一行是可读的,您可以在6
处看到正确的键和正确的明文。第一个挑战是:
这与我们之前看到的类似。密钥是一个单位数字,它将解密为可读的内容。下面是一个十六进制格式的较长示例:
密钥是两位 ASCII 码,因此您必须尝试 100 个选项才能找到将其转换为可读字符串的方法。
在本章中,在设置 Python 之后,我们介绍了简单替换密码、Caesar 密码以及base64
编码。我们一次收集六位数据,而不是一次收集八位数据,然后我们研究了异或编码,即根据密钥逐个翻转位。我们还看到了一个非常简单的真值表。您执行的挑战是在没有密钥的情况下破解 Caesar 密码,通过反转它来破解base64
以获得原始字节,以及在不知道密钥的情况下通过尝试所有可能密钥的蛮力攻击来破解 XOR 加密。在第 2 章哈希中,我们将介绍不同类型的哈希算法。**