Introduction to CryptoHack
Introduction to CryptoHack
cvestoneASCII
ASCII is a 7-bit encoding standard which allows the representation of
text using the integers 0-127.
ASCII 是一种 7 位编码标准,允许使用 0 至 127 的整数来表示文本。
Using the below integer array, convert the numbers to their
corresponding ASCII characters to obtain a flag.
使用下方的整数数组,将数字转换为对应的 ASCII 字符以获取一个标志。
1 | [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125] |
In Python, the chr()
function can be used to convert an
ASCII ordinal number to a character (the ord()
function
does the opposite).
在 Python 中,可以使用 chr()
函数将 ASCII
序数转换为字符( ord()
函数则执行相反操作)。
sollution
1 | src = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125] |
Hex
When we encrypt something the resulting ciphertext commonly has bytes
which are not printable ASCII characters. If we want to share our
encrypted data, it’s common to encode it into something more
user-friendly and portable across different systems.
当我们对某些内容进行加密时,生成的密文通常包含不可打印的 ASCII
字符。如果我们需要共享加密数据,通常会将其编码为更用户友好且能在不同系统间便携传输的形式。
Hexadecimal can be used in such a way to represent ASCII strings.
First each letter is converted to an ordinal number according to the
ASCII table (as in the previous challenge). Then the decimal numbers are
converted to base-16 numbers, otherwise known as hexadecimal. The
numbers can be combined together, into one long hex string.
十六进制可以这样用来表示 ASCII 字符串。首先根据 ASCII
表将每个字母转换为对应的序号数字(如先前挑战所示)。然后将这些十进制数字转换为基数为
16
的数字,即十六进制。这些数字可以组合在一起,形成一个长十六进制字符串。
Included below is a flag encoded as a hex string. Decode this back
into bytes to get the flag.
下方包含一个以十六进制字符串编码的标志。将其解码回字节即可获得该标志。
1 | 63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d |
In Python, the
bytes.fromhex()
function can be used to convert hex to bytes. The.hex()
instance method can be called on byte strings to get the hex representation.
在 Python 中,bytes.fromhex()
方法可用于将十六进制转换为字节。可以在字节字符串上调用.hex()
实例方法来获取其十六进制表示形式。
Resources:
- ASCII
table
- Wikipedia:
Hexadecimal
sollution
1 | src = '63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d' |
因为计算机处理原始数据时(如加密算法、网络传输、文件存储等)都需要使用字节(bytes)这种二进制格式。所以必须先将字符串转换为字节序列。
Base64
Another common encoding scheme is Base64, which allows us to
represent binary data as an ASCII string using an alphabet of 64
characters. One character of a Base64 string encodes 6 binary digits
(bits), and so 4 characters of Base64 encode three 8-bit bytes.
另一种常见的编码方案是 Base64,它允许我们使用 64
个字符的字母表将二进制数据表示为 ASCII 字符串。Base64
字符串的一个字符编码 6 个二进制数字(位),因此 4 个 Base64
字符可以编码三个 8 位字节。
Base64 is most commonly used online, so binary data such as images
can be easily included into HTML or CSS files.
Base64 最常用于在线场景,因此像图像这样的二进制数据可以轻松地包含在 HTML
或 CSS 文件中。
Take the below hex string, decode it into bytes and
then encode it into Base64.
将下面的十六进制字符串解码为字节,然后将其编码为 Base64。
1 | 72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf |
In Python, after importing the base64 module with
import base64
, you can use thebase64.b64encode()
function. Remember to decode the hex first as the challenge description states.
在 Python 中,使用import base64
导入 base64 模块后,你可以使用base64.b64encode()
函数。记得按照挑战描述先对十六进制进行解码。
sollution
1 | import base64 |
Bytes and Big Integers
Cryptosystems like RSA works on numbers, but messages are made up of
characters. How should we convert our messages into numbers so that
mathematical operations can be applied?
像 RSA
这样的加密系统基于数字运算,但消息由字符组成。我们应如何将消息转换为数字,以便应用数学运算?
The most common way is to take the ordinal bytes of the message,
convert them into hexadecimal, and concatenate. This can be interpreted
as a base-16/hexadecimal number, and also represented in
base-10/decimal.
最常见的方法是提取消息的字节序,将其转换为十六进制并拼接。这可以视为一个基数为
16 的十六进制数,也可以用基数为 10 的十进制表示。
To illustrate: 例如:
1 | message: HELLO |
Python’s PyCryptodome library implements this with the methods
bytes_to_long()
andlong_to_bytes()
. You will first have to install PyCryptodome and import it withfrom Crypto.Util.number import *
. For more details check the FAQ.
Python 的 PyCryptodome 库通过方法bytes_to_long()
和long_to_bytes()
实现此功能。首先需安装 PyCryptodome 并使用from Crypto.Util.number import *
导入。更多详情请查阅常见问题解答。
Convert the following integer back into a message:
将以下整数转换回消息:
1 | 11515195063862318899931685488813747395775516287289682636499965282714637259206269 |
sollution
1 | pip install PyCryptodome |
1 | from Crypto.Util.number import * |
XOR Starter
XOR is a bitwise operator which returns 0 if the bits are the same,
and 1 otherwise. In textbooks the XOR operator is denoted by
⊕
, but in most challenges and programming languages you
will see the caret ^
used instead.
异或是一种按位运算符,当两个位相同时返回 0,否则返回
1。在教科书中,异或运算符用⊕
表示,但在大多数挑战和编程语言中,你会看到用脱字符 ^
代替。
A | B | Output |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
For longer binary numbers we XOR bit by
bit: 0110 ^ 1010 = 1100
. We can XOR integers by first
converting the integer from decimal to binary. We can XOR strings by
first converting each character to the integer representing the Unicode
character.
对于较长的二进制数,我们逐位进行异或运算: 0110 ^ 1010 = 1100
。可以通过先将十进制整数转换为二进制来对整数进行异或。对于字符串,可以先将每个字符转换为表示
Unicode 字符的整数再进行异或。
Given the string label
, XOR each character with the
integer 13
. Convert these integers back to a string and
submit the flag as crypto{new_string}
.
给定字符串 label
,将每个字符与整数 13
进行异或运算。将这些整数转换回字符串后,以 crypto{new_string}
格式提交标志。
sollution
1 | # way1-pure |
XOR Properties
In the last challenge, you saw how XOR worked at the level of bits.
In this one, we’re going to cover the properties of the XOR operation
and then use them to undo a chain of operations that have encrypted a
flag. Gaining an intuition for how this works will help greatly when you
come to attacking real cryptosystems later, especially in the block
ciphers category.
在上一个挑战中,你已经了解了异或(XOR)在比特层面的运作方式。这一次,我们将探讨异或运算的特性,并利用它们来解构一系列加密了旗帜的操作链。理解其工作原理将极大地帮助你在后续攻击实际加密系统时,尤其是在区块密码类别中。
There are four main properties we should consider when we solve
challenges using the XOR operator
当我们使用异或运算符解决挑战时,需要考虑四个主要特性 Commutative:
A ⊕ B = B ⊕ A
交换律: Associative:
A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C
结合律: Identity:
A ⊕ 0 = A
恒等性: Self-Inverse: A ⊕ A = 0
自反性:
Let’s break this down. Commutative means that the order of the XOR
operations is not important. Associative means that a chain of
operations can be carried out without order (we do not need to worry
about brackets). The identity is 0, so XOR with 0 “does nothing”, and
lastly something XOR’d with itself returns zero.
让我们逐一解析。交换律意味着异或操作的顺序不重要;结合律表示操作链可以无序执行(无需担心括号);单位元是
0,因此与 0 异或“不产生任何效果”;最后,任何数与自身异或将返回零。
Let’s put this into practice! Below is a series of outputs where
three random keys have been XOR’d together and with the flag. Use the
above properties to undo the encryption in the final line to obtain the
flag.
让我们将其付诸实践!以下是三个随机密钥经过异或运算并与标志位结合后的一系列输出结果。利用上述特性,在最后一行撤销加密操作以获取标志位。
1 | KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313 |
Before you XOR these objects, be sure to decode from hex to bytes.
在对这些对象进行异或操作前,请确保先将十六进制解码为字节形式。
sollution
1 | """ |
第一种计算方式比较复杂,并且看起来没有任何必要,因为这题只需要用到xor其中的部分特性就能快速解决,但第一种方式的思路几乎把xor的所有特性都包含到了,有助于我们加强对xor特性的运用,具有参考意义。
另外,除了上述用脚本的方式,还可以采用Cyberchef工具来完成,可参考Cesar师傅的文章
Favourite byte
For the next few challenges, you’ll use what you’ve just learned to
solve some more XOR puzzles.
接下来的几个挑战中,你将运用刚学到的知识解决更多异或谜题。
I’ve hidden some data using XOR with a single byte, but that byte is
a secret. Don’t forget to decode from hex first.
我用单个字节作为密钥对数据进行了异或加密,但该字节是保密的。别忘了先进行十六进制解码。
1 | 73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d |