【笔记】【THM】Introduction to Cryptography(密码学简介)

【THM】Introduction to Cryptography(密码学简介)-学习

本文相关的TryHackMe实验房间链接:https://tryhackme.com/r/room/cryptographyintro

本文相关内容:了解 AES、Diffie-Hellman 密钥交换、哈希、PKI 和 TLS 等加密算法。

(大部分为机翻,若有错误请指出)

Room Banner

介绍

这个房间的目的是向各位介绍基本的密码学概念,例如:

  • 对称加密,例如 AES
  • 非对称加密,例如 RSA
  • Diffie-Hellman 密钥交换
  • hashing
  • PKI(公开秘钥基础设施)

假设您要发送一条消息,除了预期的收件人之外,没有人能理解。你会怎么做?

Top Secret Document with the words WUB KDFN PH

最简单的密码之一是凯撒密码,在 2000 多年前使用。Caesar Cipher 将字母向左或向右移动固定位数。考虑向右移动 3 进行加密的情况,如下图所示。

Illustration of Caesar cipher encryption

收件人需要知道文本已向右移动了 3 才能恢复原始邮件。

Illustration of Caesar cipher decryption

使用相同的密钥加密“TRY HACK ME”,我们得到“WUB KDFN PH”。

我们上面描述的凯撒密码可以使用 1 到 25 之间的密钥。当密钥为 1 时,每个字母移动一个位置,其中 A 变为 B,Z 变为 A。当密钥为25 时,每个字母移动 25 个位置,其中 A 变为 Z,B 变为 A。密钥为 0 表示没有变化;此外,密钥为 26 也不会导致任何变化,因为它会导致一完全轮回。因此,我们得出结论,凯撒密码的密钥空间为 25;用户可以选择 25 种不同的密钥。

假设您截获了使用凯撒密码加密的信息是:“YMNX NX FQUMF GWFAT HTSYFHYNSL YFSLT MTYJQ RNPJ”。我们被要求在不知道密钥的情况下解密它。我们可以通过使用蛮力来尝试这一点,即,我们可以尝试所有可能的密钥,看看哪一个最有意义。在下图中,我们注意到密钥为 5 时最有意义,“THIS IS ALPHA BRAVO CONTACTING TANGO HOTEL MIKE“。

Decrypting a ciphertext by trying all possible keys, i.e., by brute force

凯撒密码被认为是一种替换密码,因为字母表中的每个字母都被另一个字母替换。

另一种类型的密码称为变位密码,它通过改变字母的顺序来加密消息。让我们考虑下图中的一个简单的换位密码。我们从明文开始,“THIS IS ALPHA BRAVO CONTACTING TANGO HOTEL MIKE”,还得加上密钥。在我们通过将明文的字母按列排序竖向填写进格子后,我们根据密钥重新排列,然后按行横向读取。

换句话说,我们按列写入,按行读取。另外请注意,在此示例中,我们忽略了明文中的所有空格。生成的密文“NPCOTGHOTH...”按行读取。换句话说,换位密码只是重新排列字母的顺序,这与替换密码不同,替换密码在不改变字母顺序的情况下替换字母。42351

Illustration of a transposition cipher

此关卡介绍了简单的替换和变位密码,并将它们应用于由字母字符组成的明文。

若要使加密算法被认为是安全的,应该做到让恢复原始消息(即明文)是不可行的。(用数学术语来说,我们需要一个题,即一个不能在多项式时间内解决的问题(时间复杂度要高)。

我们可以在多项式时间内解决问题,即使对于很长的密文输入也是可行的,尽管计算机可能需要相当长的时间才能完成。

如果加密消息可以在一周内被破解,则使用的加密将被视为不安全。但是,如果加密信息可以在 100 万年内被破解,那么加密将被认为实际上是安全的。

考虑单字母替换密码,其中每个字母都映射到一个新字母。例如,在英语中,您将“a”映射到 26 个英文字母之一,然后将“b”映射到剩余的 25 个英文字母之一,然后将“c”映射到剩余的 24 个英文字母之一,依此类推。

例如,我们可以选择字母表“abcdefghijklmnopqrstuvwxyz”中的字母分别映射到“xpatvrzyjhecsdikbfwunqgmol”。换句话说,“a”变成“x”,“b”变成“p”,依此类推。收件人需要知道密钥“xpatvrzyjhecsdikbfwunqgmol”才能成功解密加密邮件。

此算法可能看起来非常安全,特别是因为尝试其他所有可能的密钥是不可行的。但是,可以使用不同的技术来使用这种加密算法破解密文。

这种算法的一个弱点是字母频率。在英语文本中,最常见的字母是“e”、“t”和“a”,因为它们的出现频率分别为 13%、9.1% 和 8.2%。此外,在英语文本中,最常见的首字母是“t”、“a”和“o”,因为它们分别出现在 16%、11.7% 和 7.6% 处。除此之外,大多数消息单词都是字典单词,您将能够立即使用字母替换密码破解加密文本。

我们真的不需要使用加密密钥来解密接收到的这条密文:“Uyv sxd gyi siqvw x sinduxjd pvzjdw po axffojdz xgxo wsxcc wuidvw.“如下图所示,使用quipqiup这样的网站,需要一点时间才能发现原文是“The man who moves a mountain begins by carrying away small stones”。此示例清楚地表现出这种算法已被破解,不能够应用于机密通信。

Screenshot of the quipquip website

答题

您已收到以下加密消息:

“Xjnvw lc sluxjmw jsqm wjpmcqbg jg wqcxqmnvw;xjzjmmjd lc wjpm sluxjmw jsqm bqccqm zqy.”Zlwvzjxj Zpcvcol

你可以猜到这是一句名言。是谁说的?

WP

我们进入网站quipqiup - cryptoquip and cryptogram solver即可根据词频解密简单的替换密码

image-20240718180141101

对称加密

让我们回顾一些术语:

  • 加密算法密码:此算法定义加密和解密过程。
  • 密钥:加密算法需要密钥才能将明文转换为密文,反之亦然。
  • 明文是我们要加密的原始消息
  • 密文是经过加密后的消息

对称加密算法使用相同的密钥进行加密和解密。因此,通信双方需要在能够交换任何消息之前就密钥达成一致。

在下图中,发送方向加密过程提供了明文和获取密文的密钥。密文通常通过某种通信信道发送。使用密钥加密的通用框图

在另一端,接收方使用发送方使用的相同密钥提供解密过程,以便从接收到的密文中恢复原始明文。如果不知道密钥,接收方将无法恢复明文。

使用密钥解密的通用框图

美国国家标准与技术研究院(NIST)于1977年发布了数据加密标准(DES)。DES是一种对称加密算法,使用56位大小的密钥。1997年,破解使用DES加密信息的挑战得到了解决。因此,证明使用暴力搜索找到密钥并破解使用DES加密的消息是可行的。1998年,DES密钥在56小时内被破解。这些情况表明DES不再被认为是安全的。

NIST于2001年发布了高级加密标准(AES)。与DES一样,它也是一种对称加密算法;然而,它使用128、192或256位大小的密钥,它仍然被认为是安全的,并且今天仍在使用。AES多次重复以下四种转换:

  1. SubBytes(state) :此转换查找给定替换表(S-box)中的每个字节,并用相应的值替换它。是16字节,即128位,保存在一个4 × 4的数组中。 state
  2. ShiftRows(state) :第二行移动一位,第三行移动两位,第四行移动三位。如下图所示。
  3. MixColumns(state) :每列乘以一个固定的矩阵(4 × 4数组)。
  4. AddRoundKey(state) :通过异或操作向状态中添加一个圆key。

Illustration of the ShiftRows function when applied on a four by four array

转换轮次的总数取决于密钥的大小。

不要担心,如果你觉得这种加密算法非常神秘,那就对了!我们的目的不是学习AES如何工作的细节,也不是将其实现为一个编程库;目的是了解古代加密算法和现代加密算法在复杂性上的差异。如果您想深入了解细节,可以查看AES规范,包括其发布的标准FIPS PUB 197中的伪代码和示例。

(加密原理动画解释5分钟搞定AES算法

除了AES之外,许多其他对称加密算法也被认为是安全的。下面是GPG (GnuPG) 2.37.7支持的对称加密算法列表,例如:

加密算法 笔记
AES, AES192, AES256 AES,密钥大小为128、192和256位
IDEA 国际数据加密算法(IDEA)
3DES 三倍的 DES(数据加密标准),并且基于DES。我们应该注意到3DES将在2023年弃用,2024年不允许使用。
CAST5 也称为CAST-128。一些资料表明,CAST代表其作者的名字:卡莱尔·亚当斯和斯塔福德·塔瓦雷斯。
BLOWFISH 由Bruce Schneier设计
TWOFISH 由Bruce Schneier设计,源自BLOWFISH
CAMELLIA128, CAMELLIA192, CAMELLIA256 由三菱电机和日本NTT设计。它的名字来源于山茶花。

目前所提到的算法都是分组密码对称加密算法。分组密码算法将输入(明文)转换为块并对每个块进行加密。一个块通常是128位。在下面的图中,我们要加密明文“TANGO HOTEL MIKE”,共16个字符。第一步是用二进制表示它。如果我们使用ASCII,“T”十六进制格式是“0x54”,“A”十六进制格式是“0x41”,以此类推。每两个十六进制数字组成8位,代表一个字节。128位的块实际上是16个字节,用4 × 4数组表示。128位块作为一个单元馈入加密方法。

Example of a block cipher encryption algorithm applied on a four by four array

另一种对称加密算法是流密码,它一个字节一个字节地加密明文。考虑这样一个情况,我们想要加密消息“TANGO HOTEL MIKE”;每个字符都需要转换成二进制表示。如果我们使用ASCII,“T”十六进制格式是“0x54”,“A”十六进制格式是“0x41”,以此类推。加密方法每次只处理一个字节。如下图所示:

Example of a stream cipher encryption algorithm applied on an array of bytes

对称加密解决了本文讨论的许多安全问题。假设Alice和Bob见面,选择了一种加密算法,并就一个特定的密钥达成了一致。我们假设所选择的加密算法是安全的,并且密钥是安全的。让我们来看看我们可以实现什么:

  • 机密性:如果Eve截获了加密信息,她将无法恢复明文。因此,Alice和Bob之间交换的所有消息都是机密的,只要它们是加密发送的。
  • 完整性:当Bob接收到一条加密的消息并使用他与Alice商定的密钥成功解密时,Bob可以确保没有人可以通过通道篡改消息。当使用安全的现代加密算法时,对密文的任何微小修改都会阻止成功解密,或者导致解密出的明文出现乱码。
  • 真实性:能够使用密钥解密密文也证明了消息的真实性,因为只有Alice和Bob知道密钥。

我们才刚刚开始,我们现在知道了如何维护机密性,检查完整性并确保交换消息的真实性。

更实际和有效的方法将在以后的任务中提出。现在的问题是,这种加密算法是否可以扩展。

对于Alice和Bob,我们需要一把钥匙。如果我们有Alice、Bob和Charlie,我们需要三把钥匙:一把给Alice和Bob,另一把给Alice和Charlie,第三把给Bob和Charlie。然而,钥匙的数量增长很快;100个用户之间的通信需要近5000个不同的密钥。(如果你对它背后的数学很好奇,那就是99+98+97…+1 = 4950)。

此外,如果一个系统遭到破坏,他们需要创建新的密钥,以便与其他99个用户一起使用。另一个问题是找到一个与所有其他用户交换密钥的安全通道。显然,这种情况很快就会失控。

在下一个任务中,我们将介绍非对称加密。使用非对称加密解决的一个问题是,100个用户只需要共享总共100个密钥就可以安全通信。(如前所述,对称加密将需要大约5000个密钥来保护100个用户的通信。)

有许多程序可用于对称加密。我们将重点关注两种,它们也广泛用于非对称加密:

  • GNU隐私保护
  • OpenSSL项目

GNU隐私保护

GNU Privacy Guard,也称为GnuPG或GPG,实现了OpenPGP标准。

我们可以使用GnuPG (GPG)加密文件,使用以下命令:

gpg --symmetric --cipher-algo CIPHER message.txt

其中CIPHER为加密算法名称。可以使用该命令查看支持的密码:

gpg --version

加密后的文件将保存为message.txt.gpg

默认输出是二进制OpenPGP格式;但是,如果您希望创建一个可以在任何文本编辑器中打开的ASCII加密输出,则应该添加该选项:--armor

例如: gpg --armor --symmetric --cipher-algo CIPHER message.txt

可以使用以下命令解密:

gpg --output original_message.txt --decrypt message.gpg

OpenSSL项目

OpenSSL项目负责维护OpenSSL软件。

我们可以使用以下命令使用OpenSSL加密文件:

openssl aes-256-cbc -e -in message.txt -out encrypted_message

我们可以使用以下命令解密输出文件:

openssl aes-256-cbc -d -in encrypted_message -out original_message.txt

为了提高加密的安全性和抗暴力攻击的弹性,我们可以添加使用基于密码的密钥派生函数2 (PBKDF2)-pbkdf2;此外,我们可以指定密码的迭代次数-iter NUMBER,以使用它派生加密密钥。要迭代10,000次,前面的命令将变成:

openssl aes-256-cbc -pbkdf2 -iter 10000 -e -in message.txt -out encrypted_message

因此,解密命令变成:

openssl aes-256-cbc -pbkdf2 -iter 10000 -d -in encrypted_message -out original_message.txt

在接下来的问题中,我们将使用攻击机进行 gpgopenssl对称加密。

此任务所需的文件位于/root/Rooms/cryptographyintro/task02

此任务附带的zip文件是任务2、3、4、5和6中的问题文件。

答题

1.使用 gpg 用密钥 s!kR3T55 解密文件 quote01 加密(使用AES256)。文件中的第三个单词是什么?

2.使用 openssl 对用密钥 s!kR3T55 加密(使用AES256-CBC)的文件 quote02 进行解密。文件中的第三个单词是什么?

3.使用 gpg 解密用密钥 s!kR3T55 加密(使用CAMELLIA256)的文件 quote03 。文件中的第三个单词是什么?

WP

1.使用命令:

gpg --output original_message.txt --decrypt quote01.txt.gpg

并且输入秘钥:”s!kR3T55“成功获取明文

image-20240718190845554

2.使用命令:

openssl aes-256-cbc -d -in quote02 -out original_message.txt

并且输入秘钥:”s!kR3T55“成功获取明文

image-20240718191319272

3.使用命令:

gpg --output original_message.txt --decrypt quote03.txt.gpg

并且输入秘钥:”s!kR3T55“成功获取明文

image-20240718191617304

image-20240718195708503

非对称加密

对称加密要求用户找到一个安全的通道来交换密钥。通过安全通道,我们主要关注保密性和完整性。换句话说,我们需要一个没有第三方可以窃听和读取流量的通道;此外,没有人可以更改发送的消息和数据。

非对称加密使得在没有安全通道的情况下交换加密消息成为可能;我们只需要一个可靠的渠道。通过可靠的渠道,我们主要关心的是渠道的完整性,而不是保密性。

当使用非对称加密算法时,我们将生成一个密钥对:一个公钥和一个私钥。公钥与全世界共享,或者更具体地说,与想要与我们安全通信的人共享。私钥必须安全地保存,我们绝不能让任何人访问它。此外,即使知道公钥,也无法获得私钥。

这个密钥对是如何工作的?

如果消息是用一个密钥加密的,则可以用另一个密钥解密。换句话说:

  • 如果Alice使用Bob的公钥加密消息,则只能使用Bob的私钥解密消息。
  • 相反,如果Bob使用他的私钥加密消息,则只能使用Bob的公钥解密消息。

保密

我们可以使用非对称加密,通过使用接收方的公钥加密消息来实现机密性。从下面两张图中我们可以看到:

Alice想要确保她与Bob的通信是保密的。她使用Bob的公钥加密消息,Bob使用他的私钥解密消息。例如,Bob的公钥预计将发布在公共数据库或他的网站上。

When using asymmetric encryption, Alice encrypts the messages using Bob's public key before sending them to Bob. Bob decrypts the messages using his private key.

当Bob想要回复Alice时,他使用Alice的公钥加密他的消息,而Alice可以使用她的私钥解密。

When using asymmetric encryption, Bob encrypts the messages using Alice's public key before sending them to Alice. Alice decrypts the messages using her private key.

换句话说,在确保消息的机密性的同时,与Alice和Bob通信变得很容易。唯一的要求是,各方都有自己的公钥可供发送方使用。

注意:在实践中,对称加密算法允许比非对称加密更快的操作;因此,我们将在后面介绍如何使用这两种方法的优点。

完整性、真实性和不可否认性

除了机密性之外,非对称加密还可以解决完整性、真实性和不可否认性问题。假设Bob想要发表一个声明,并且希望每个人都能够确认这个声明确实来自他。Bob需要使用他的私钥加密消息;接收方可以使用Bob的公钥解密它。如果使用Bob的公钥成功解密消息,则意味着使用Bob的私钥对消息进行了加密。(实际上,他会对原始消息的哈希值进行加密。稍后我们将对此进行详细说明。)

使用Bob的公钥成功解密可以得出一些有趣的结论。

  • 首先,信息没有被改变(通信渠道);这证明了消息的完整性。
  • 其次,知道没有人可以访问Bob的私钥,我们可以确定这条消息确实来自Bob;这证明了消息的真实性。
  • 最后,因为除了Bob以外没有人可以访问Bob的私钥,Bob不能否认发送了这条消息;这建立了不可否认性。

To prove authenticity using asymmetric encryption, Bob encrypts the message using his private key and the recipients can decrypt it using Bob’s public key.

我们已经看到了非对称加密如何帮助建立机密性、完整性、真实性和不可否认性。在实际场景中,非对称加密在加密大型文件和大量数据时可能相对较慢。在另一项任务中,我们将看到如何将非对称加密与对称加密结合使用,以相对更快地实现这些安全目标。

RSA

RSA得名于它的发明者Rivest、Shamir和Adleman。它的工作原理如下:

1.选择两个质数p 和q ,算出他们的乘积n = p × q ,算出对应的欧拉函数φ ( n )(利用性质φ ( n ) = φ ( p ) × φ ( q ) = ( p − 1 ) ( q − 1 ))。
2.选择一个e ,使得e < φ ( n )并且e 与φ ( n ) 互质。
3.算出e 的一个相对于φ ( n )的模反元素d 。
4.( e , n ) 为公钥,( d , n ) 为私钥,信息(明文)m 长度小于n 。
5.加密:c=m^e(mod n)
6.解密:m=c^d~(mod n)

如果上面的数学方程看起来太复杂,不要担心;你不需要数学就能使用RSA,因为它很容易通过程序和编程库获得。

RSA安全性依赖于质数分解,这是一个难题。p乘以q很容易;然而,在给定n的情况下找到p和q是非常耗时的。此外,为了保证安全性,p和q应该是相当大的数字,例如,每个都是1024位(这是一个超过300位的数字)。值得注意的是,RSA依赖于安全的随机数生成,与其他非对称加密算法一样。如果对手可以猜出p和q,那么整个系统将被认为是不安全的。

让我们考虑下面的实际示例。

  1. Bob选择了两个素数:p = 157和q = 199。他计算出N = 31243。

  2. 然后ϕN (N) =30888,鲍勃选择e = 163于是d = 379

    是因为e×d = 163×379 = 61777并且61777 mod 30888 = 1。公钥为(31243,163),私钥为(31243,379)。

  3. 假设要加密的值是x = 13,那么Alice会计算并发送y = x^e mod N = 13^163 mod 31243 = 16342。

  4. Bob将通过计算x = y ^d mod N = 16341^379 mod 31243 = 13来解密接收到的值。

前面的例子是为了更好地理解它背后的数学原理。要查看p和q的实值,让我们使用 openssl 之类的工具创建一个实对。

user@TryHackMe$ openssl genrsa -out private-key.pem 2048

user@TryHackMe$ openssl rsa -in private-key.pem -pubout -out public-key.pem
writing RSA key

user@TryHackMe$ cat public-key.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAymcAeYg1ohPQLHu7u9l1
UutN8bCP7r6czRX2zrQrpElYrm5mHERi1xweWEhTJ/0Q13FJcHLGtLbdQc0rGpOd
DnYJBuzrqXU2hC7E7dlqLsj63NPADqlOGYCGCWnm/HGM2WuVtDXqRitN4zeNKEWI
QmEctfucopZx5AVJ1vTn+qMv/0D6QU7Mm65MTSYg1SCRA0D0N9NLMj4rYlLOIr5q
5g3iunAE4tCROMcHf7fxWMuWdJTdtxTv7+4P5XGkWrWriO22JFHp9N22Fm96V9jH
7aASRkIZvQFmx+1dl7btZDhsm2ezU07LBabv9efj0gIwz6P3mTJVm+wxaDH6jiXB
dwIDAQAB
-----END PUBLIC KEY-----

user@TryHackMe$ openssl rsa -in private-key.pem -text -noout
Private-Key: (2048 bit, 2 primes)
modulus:
    00:ca:67:00:79:88:35:a2:13:d0:2c:7b:bb:bb:d9:
    75:52:eb:4d:f1:b0:8f:ee:be:9c:cd:15:f6:ce:b4:
    2b:a4:49:58:ae:6e:66:1c:44:62:d7:1c:1e:58:48:
    53:27:fd:10:d7:71:49:70:72:c6:b4:b6:dd:41:cd:
    2b:1a:93:9d:0e:76:09:06:ec:eb:a9:75:36:84:2e:
    c4:ed:d9:6a:2e:c8:fa:dc:d3:c0:0e:a9:4e:19:80:
    86:09:69:e6:fc:71:8c:d9:6b:95:b4:35:ea:46:2b:
    4d:e3:37:8d:28:45:88:42:61:1c:b5:fb:9c:a2:96:
    71:e4:05:49:d6:f4:e7:fa:a3:2f:ff:40:fa:41:4e:
    cc:9b:ae:4c:4d:26:20:d5:20:91:03:40:f4:37:d3:
    4b:32:3e:2b:62:52:ce:22:be:6a:e6:0d:e2:ba:70:
    04:e2:d0:91:38:c7:07:7f:b7:f1:58:cb:96:74:94:
    dd:b7:14:ef:ef:ee:0f:e5:71:a4:5a:b5:ab:88:ed:
    b6:24:51:e9:f4:dd:b6:16:6f:7a:57:d8:c7:ed:a0:
    12:46:42:19:bd:01:66:c7:ed:5d:97:b6:ed:64:38:
    6c:9b:67:b3:53:4e:cb:05:a6:ef:f5:e7:e3:d2:02:
    30:cf:a3:f7:99:32:55:9b:ec:31:68:31:fa:8e:25:
    c1:77
publicExponent: 65537 (0x10001)
privateExponent:
    10:fe:00:be:33:3f:3d:72:28:61:f3:a9:59:25:f2:
    81:99:9b:9b:94:d5:20:98:04:15:fb:a8:12:c6:71:
    7b:83:64:dc:90:0c:26:87:5f:3c:eb:f1:68:3b:fa:
    2f:3b:41:b4:b4:a0:13:be:af:0b:f0:e6:36:66:01:
    1e:64:12:25:6a:a7:6b:5b:6c:95:77:6f:b2:3d:32:
    ef:3c:f7:7b:22:08:5d:8d:b1:6c:09:ae:b2:d9:65:
    67:58:ea:b9:7a:d6:f6:51:df:e9:97:35:29:da:ec:
    d9:0c:8a:df:3c:a7:29:db:79:4b:95:ea:1a:84:42:
    df:7f:ca:29:2f:ba:62:02:37:05:c0:b0:c2:ff:42:
    6b:fb:e1:36:40:10:ae:11:0f:d8:87:2f:fe:10:2e:
    a4:60:de:ff:fe:c8:ab:0b:29:fa:6c:20:ec:87:33:
    46:c0:cd:96:36:cb:9b:ca:81:17:e5:c3:eb:34:b2:
    83:0f:52:cc:e9:68:bd:cb:d2:85:2f:fe:c4:47:76:
    df:94:69:ce:7b:8a:50:71:36:96:e6:35:fb:fb:b4:
    4a:ac:63:9b:9d:1b:bb:32:71:31:45:a2:25:33:cc:
    f7:a5:fb:9f:66:b1:4e:30:ce:9d:71:e8:fa:7d:5f:
    33:a0:c1:94:0a:b7:b7:f3:16:7e:4f:ad:89:3d:ba:
    51
prime1:
    00:e0:3d:87:b3:d3:1f:d2:c6:66:23:83:a5:95:d5:
    20:35:f8:d8:c0:94:cf:cc:d2:04:d4:e4:ef:cf:c2:
    94:00:10:cd:d1:4a:df:09:4e:7e:95:f8:70:08:b1:
    20:98:8a:e3:88:f7:cc:a8:32:62:32:68:f6:1f:c0:
    fb:c1:71:41:8c:21:a3:ff:20:e6:96:d0:6e:4b:66:
    61:08:d0:b7:26:48:27:62:a7:d3:ff:36:55:c8:e1:
    ab:91:48:90:fb:b5:b1:92:be:90:06:a8:40:1b:2a:
    2d:53:1e:87:fc:a7:8a:57:72:0b:e5:35:71:7b:dd:
    8c:e5:b5:ab:64:7c:37:c5:0d
prime2:
    00:e7:11:ac:50:f5:dc:16:cf:20:46:77:5d:ca:16:
    29:36:35:89:95:c0:f8:4b:42:ef:03:a0:f1:ce:2e:
    1b:da:55:a9:ff:5a:28:4d:78:c5:8a:e2:55:9b:94:
    b4:56:ec:ab:1b:dd:b8:07:be:dd:d5:0f:49:90:b3:
    ed:a2:d7:78:38:24:d5:9e:7d:a2:e8:8c:e0:2a:33:
    32:21:1f:0e:6b:aa:0b:b4:11:6a:bd:8f:d9:86:3f:
    ad:42:c8:bc:42:23:21:39:8d:0c:60:f2:ca:2a:00:
    0a:8e:de:fb:1a:3c:51:9d:f2:dc:0a:59:80:d6:a4:
    47:5c:02:a3:d0:30:1d:47:93
[...]

我们执行了三个命令:

  • openssl genrsa -out private-key.pem 2048 :对于 openssl ,我们使用 genrsa 来生成RSA私钥。使用 -out ,我们指定生成的私钥保存为 private-key.pem 。我们添加了 2048 来指定2048位的密钥大小。
  • openssl rsa -in private-key.pem -pubout -out public-key.pem :使用 openssl ,我们指定我们使用RSA算法与 rsa 选项。我们指定要使用 -pubout 获取公钥。最后,我们使用 -in private-key.pem 设置私钥作为输入,并使用 -out public-key.pem 保存输出。
  • openssl rsa -in private-key.pem -text -noout :我们很想看到真正的RSA变量,所以我们使用 -text -noout 。p, q, N, e,和d的值分别是 prime1 , prime2 , modulus , publicExponentprivateExponent

如果我们已经有了接收方的公钥,我们可以使用命令 openssl pkeyutl -encrypt -in plaintext.txt -out ciphertext -inkey public-key.pem -pubin对其进行加密

接收方可以使用命令 openssl pkeyutl -decrypt -in ciphertext -inkey private-key.pem -out decrypted.txt解密它。

答题

1.Bob收到了Alice发给他的文件 ciphertext_message 。你可以在同一个文件夹里找到你需要的密钥。原始明文的第一个字是什么?

2.看一下Bob的RSA私钥。p的最后一个字节是什么?

WP

1.Alice发给Bob的文件应该是用Bob的公钥加密的,Bob要解密应该使用Bob的私钥,使用以下命令:

openssl pkeyutl -decrypt -in ciphertext_message -inkey private-key-bob.pem -out decrypted.txt

image-20240718194704786

2、3.使用以下命令查看p、q、n、e、d的变量:

openssl rsa -in private-key-bob.pem -text -noout

image-20240718195626036

image-20240718195733408

Diffie-Hellman 密钥交换技术

Alice和Bob可以通过不安全的信道进行通信。所谓不安全,我们指的是存在窃听者,他们可以读取在这个通道上交换的消息。在这种情况下,Alice和Bob怎么能就一个密钥达成一致呢?一种方法是使用Diffie-Hellman密钥交换。

Diffie-Hellman是一种非对称加密算法。它允许在公共通道上交换秘密。

  1. Alice和Bob都统一q和g的值。为了使这个式子成立,q应该是一个质数,g是一个满足一定条件的小于q的数。(在模算法中,g是一个生成器。)在这个例子中,我们取q = 29, g = 3。
  2. Alice随机选择一个小于q的数a,计算出A = (g^a ) mod q,其中a必须保密;但是A被发送给Bob。假设Alice选择数字a = 13并计算出A = 3^13 %29 = 19并将其发送给Bob。
  3. Bob随机选择一个小于q的数字b,计算出B = (g^b ) mod q, Bob必须对b保密;但是他把B送给了Alice。让我们考虑Bob选择数字b = 15并计算B= 3^15 %29 = 26的情况。他继续把它寄给Alice。
  4. Alice接收到B,计算key = B^a mod q。数值示例key = 26^13 mod 29 = 10。
  5. Bob接收到A,计算出key = A^b mod q。数值示例key = 19^15 mod 29 = 10。

我们可以看到Alice和Bob得到了同一个秘密密钥。

尽管窃听者已经知道了q、g、A和B的值,但他们无法计算出Alice和Bob交换的密钥。以上步骤总结如下图所示。

Graphical illustration showing a numeric example of the five steps of Diffie-Hellman

虽然我们选择的数字可以很容易地找到a和b,即使不使用计算机,现实世界的例子也会选择长度为256位的q。用十进制表示,就是115右边加75个零(我也不知道怎么读,但有人告诉我它的读法是115 qutuorvigintillion)。如此大的q将使得即使知道q、g、a和b,也无法找到a或b。

让我们看一下实际的Diffie-Hellman参数。我们可以使用 openssl 来生成它们;我们需要指定选项 dhparam 来表示我们想要生成Diffie-Hellman参数以及指定的比特大小,例如 20484096

在下面的控制台输出中,我们可以使用命令 openssl dhparam -in dhparams.pem -text -noout 查看素数 P 和生成器 G 。(这与我们对RSA私钥所做的类似。)

user@TryHackMe$ openssl dhparam -out dhparams.pem 2048
Generating DH parameters, 2048 bit long safe prime
[...]
$ openssl dhparam -in dhparams.pem -text -noout
    DH Parameters: (2048 bit)
    P:   
        00:82:3b:9d:b5:29:31:f8:12:fe:21:e1:90:30:37:
        ac:d2:48:41:f7:d7:55:e5:d2:5d:dd:87:67:9e:bd:
        b3:97:df:05:a9:d2:d9:56:4f:66:b5:d9:d8:65:06:
        58:c3:8f:b3:0e:30:d2:9a:0b:c3:0a:56:8d:fc:0f:
        f2:e2:9e:4f:16:16:93:4e:b9:a4:c3:9c:09:2d:48:
        a2:ec:b6:97:92:63:a3:b4:75:36:3f:51:77:ca:ac:
        44:6d:99:eb:4d:4a:97:d5:4b:52:c8:07:f8:16:30:
        37:d3:b2:47:30:e6:4e:bc:6a:53:d1:9b:6a:4d:91:
        7a:4b:4f:af:3b:f0:ce:b9:ed:91:4d:8b:52:5a:3f:
        bb:6b:06:ae:32:95:7d:53:da:9b:ce:b0:ec:7d:81:
        25:05:d8:ce:ca:76:e7:d1:5a:31:13:d2:9f:62:b4:
        d5:ad:7d:cd:c9:ab:3d:28:e3:92:27:9f:f3:66:a0:
        be:61:49:cc:47:21:d8:e0:2c:e8:c6:35:4b:2f:ba:
        35:36:8f:bb:41:c6:89:b2:60:3c:62:bb:fe:bf:59:
        d3:7f:05:69:55:dc:61:1b:b4:bb:68:fa:65:1e:2e:
        46:2f:2d:21:62:d1:9f:a0:2b:aa:81:df:3a:f9:7d:
        0b:9d:0e:47:68:01:4f:6e:81:cc:4c:2a:91:fc:8c:
        f4:6f
    G:    2 (0x2)

Diffie-Hellman密钥交换算法允许双方在一个不安全的通道上就一个秘密达成一致。然而,所讨论的密钥交换很容易受到中间人(MitM)攻击;攻击者可能会回复假装成Bob的Alice,并回复假装成Alice的Bob。我们将在任务6中讨论这个问题的解决方案。

答题

1.在 dhparam.pem 文件中可以找到一组Diffie-Hellman参数。质数的位数是多少?

WP

1、2.使用以下命令即可查看dhparam.pem文件内容:

openssl dhparam -in dhparams.pem -text -noout

image-20240718202417403

image-20240718202453407

哈希

加密散列函数是一种算法,它将任意大小的数据作为输入,并返回固定大小的值(称为消息摘要或校验和)作为输出。

例如, sha256sum 计算SHA256(安全哈希算法256)消息摘要。SHA256,顾名思义,返回大小为256位(32字节)的校验和。该校验和通常使用十六进制数字书写。知道一个十六进制数字代表4位,256位校验和可以表示为64位十六进制数字。

在下面的终端输出中,我们计算了三个大小不同的文件的SHA256哈希值:4字节、275 MB和5.2 GB。使用 sha256sum 计算三个文件中每个文件的消息摘要,我们得到三个完全不同的值,它们看起来是随机的。值得强调的是,无论文件大小,结果消息摘要或校验和的长度都是相同的。特别是,4字节文件 abc.txt 和5.2 GB文件产生的消息摘要长度相等,与文件大小无关。

user@TryHackMe$ ls -lh
total 5.5G
-rw-r--r--. 1 strategos strategos    4  7月 21 12:46 abc.txt
-rw-r--r--. 1 strategos strategos 275M  2月 12 19:08 debian-hurd.img.tar.xz
-rw-r--r--. 1 strategos strategos 5.2G  4月 26 16:55 Win11_English_x64v1.iso
$ sha256sum *
c38bb113c89d8fec6475a9936411007c45563ecb7ce8acd5db7fb58c0872bda0  abc.txt
0317ff0150e0d64b70284b28c97bb788310585ea7ac46cc8139d5a3c850dea55  debian-hurd.img.tar.xz
4bc6c7e7c61af4b5d1b086c5d279947357cff45c2f82021bb58628c2503eb64e  Win11_English_x64v1.iso

但是我们为什么需要这样一个函数呢?有很多用途,特别是:

  • 存储密码:不是以明文形式存储密码,而是存储密码的散列。因此,如果发生数据泄露,攻击者将获得密码哈希列表,而不是原始密码。(在实践中,密码也被“加盐”,稍后的任务将对此进行讨论。)
  • 检测修改:对原始文件的任何微小修改都会导致哈希值的剧烈变化,即校验和。

在下面的终端输出中,我们有两个文件, text1.txttext2.txt ,它们几乎是相同的,除了(字面上)一个比特不同;字母 Tt 在其ASCII表示中只差一位。尽管我们只翻转了一个位,但很明显,SHA256的校验和是完全不同的。因此,如果我们使用安全哈希函数算法,我们可以很容易地确认是否发生了任何修改。这可以帮助防止故意篡改和文件传输错误。

user@TryHackMe$ hexdump text1.txt -C
00000000  54 72 79 48 61 63 6b 4d  65 0a                    |TryHackMe.|
0000000a
$ hexdump text2.txt -C
00000000  74 72 79 48 61 63 6b 4d  65 0a                    |tryHackMe.|
0000000a
$ sha256sum text1.txt
f4616fd825a10ded9af58fbaee09f3e31751d15591f9323ea68b03a0e8ac3783  text1.txt
$ sha256sum text2.txt
9ffa3533ee33998aeb1df76026f8031c8af6ccabd8393eca002d5b7471a0b536  text2.txt

一些正在使用的散列算法仍然被认为是安全的:

  • Sha224, sha256, sha384, sha512
  • 成熟的MD160

一些较旧的散列函数,如MD5 (Message Digest 5)和SHA-1,在加密上是已被破解的。通过破解,我们的意思是有可能生成与给定文件具有相同校验和的不同文件。这意味着我们可以创建一个哈希冲突。换句话说,攻击者可以使用给定的校验和创建新消息,并且不可能检测到文件或消息篡改。

HMAC

基于三列的信息验证码(HMAC)是一种信息验证码(MAC),它除了使用哈希函数外还使用加密密钥。

根据RFC2104, HMAC需要:

  • 密钥
  • Inner pad(ipad)一个常量字符串。(RFC2104使用字节 0x36 重复B次。B的值取决于所选择的哈希函数。)
  • Outer pad(opad)是一个常量字符串。(RFC2104使用字节 0x5C 重复B次。)

计算HMAC的步骤如下图所示:

1.对key追加0,使其长度为B,即使其长度与ipad的长度相同。

2.使用以⊕表示的位异或(XOR),用⊕表示,计算key⊕ipad。

3.将消息添加到步骤2的XOR输出。

4.将哈希函数应用于生成的字节流(在步骤3中)。

5.使用异或,计算key⊕opad。

6.将第4步的哈希函数输出附加到第5步的异或输出。

7.将哈希函数应用于生成的字节流(在步骤6中)以获得HMAC。

Graphical illustration showing how an HMAC is calculated

上图所示的步骤用以下公式表示:H(K⊕opad,H(K⊕ipad,text))

要在Linux系统上计算HMAC,您可以使用任何可用的工具,例如 hmac256 (或 sha224hmacsha256hmacsha384hmacsha512hmac ,其中密钥添加在选项 --key 之后)。下面我们展示了一个使用 hmac256sha256hmac 两个不同的key计算HMAC的例子。

user@TryHackMe$ hmac256 s!Kr37 message.txt
3ec65b7e80c5bf2e623e52e0528f1c6a74f605b10616621ba1c22a89fb244e65  message.txt

user@TryHackMe$ hmac256 1234 message.txt
4b6a2783631180fca6128592e3d17fb5bff6b0e563ad8f1c6afc1050869e440f  message.txt

user@TryHackMe$ sha256hmac message.txt --key s!Kr37
3ec65b7e80c5bf2e623e52e0528f1c6a74f605b10616621ba1c22a89fb244e65  message.txt

user@TryHackMe$ sha256hmac message.txt --key 1234
4b6a2783631180fca6128592e3d17fb5bff6b0e563ad8f1c6afc1050869e440f  message.txt

问题

1.order.json 文件的SHA256校验和是多少?

2.打开 order.json 文件,将 1000 改为 9000 。新的SHA256校验和是什么?

3.使用SHA256和密钥 3RfDFz82order.txt 的HMAC是什么?

WP

1.使用以下命令查看order.json文件的SHA256校验和:

sha256sum order.json

image-20240718203716956

2.使用vim更改后查看即可

image-20240718203840383

image-20240718203913452

3.使用以下命令计算密钥为3RfDFz82时order.txt文件的HMAC值:

sha256hmac order.txt --key 3RfDFz82

image-20240718204147735

没找到相关命令,那就换一个:

hmac256 3RfDFz82 order.txt

image-20240718204247843

image-20240718204326316

PKI和SSL/TLS

使用密钥交换,如Diffie-Hellman密钥交换,可以在窃听者的眼皮底下协商出一个密钥。此密钥可与对称加密算法一起使用,以确保机密通信。然而,我们前面描述的密钥交换不能免疫中间人(man -the- middle, MITM)攻击。原因是,在交换密钥时,Alice无法确保自己在与Bob通信,而Bob也无法确保自己在与Alice通信。

考虑下面的图。这是Diffie-Hellman密钥交换任务中解释的一种针对密钥交换的攻击。具体步骤如下:

  1. Alice和Bob对q和g达成了一致。任何监听通信信道的人都可以读取这两个值,包括攻击者Mallory。
  2. 像往常一样,Alice选择一个随机变量a,计算出A (A = (g^a ) mod q)并将A发送给Bob。Mallory一直在等待这一步,她选择了一个随机变量m,并计算了相应的M。Mallory一收到A,就把M发送给Bob,假装她是Alice。
  3. Bob收到M,认为是Alice发送的。Bob已经选择了一个随机变量b,并计算了相应的B;他把B发给Alice。类似地,Mallory截获消息,读取B并将M发送给Alice。
  4. Alice接收M,计算key = M^a mod q。
  5. Bob接收M,计算key = M^b mod q。

Alice和Bob认为自己在直接通信,并继续通信,而没有意识到他们正在与Mallory通信,后者可以在将消息发送给目标接收方之前阅读和修改消息。

Illustration showing the Man-in-the-Middle attack against Diffie-Hellman Key Exchange

这种敏感性需要某种机制,使我们能够确认对方的身份。这就引出了公钥基础设施(PKI)。

考虑一下通过HTTPS访问网站example.org的情况。您如何确信您确实在与 example.org 服务器通信?换句话说,你怎么能确定没有中间人在数据包到达你面前拦截并修改它们呢?答案在于网站证书。

下图显示了我们浏览example.org时得到的页面。大多数浏览器都用某种锁图标来表示加密连接。这个锁图标表示连接是通过HTTPS进行保护的,使用的是有效的证书。

Screenshot of a browser showing a lock icon for an encrypted connection

写作证书时,example.org使用的证书由DigiCert Inc.签名,如下图所示。换句话说,DigiCert确认这个证书是有效的(直到某个日期)。

Screenshot showing the validity of a website certificate

要让证书颁发机构对证书进行签名,我们需要:

1.生成证书签名请求(Generate Certificate Signing Request, CSR):你创建一个证书,并将你的公钥发送给第三方签名。

2.将你的CSR发送给证书颁发机构(CA):目的是让CA签名你的证书。另一个通常不安全的解决方案是自签名证书。

为此,接收方应该识别并信任签发证书的CA。正如我们所料,我们的浏览器信任DigiCert公司作为签名机构;否则,它将发出安全警告,而不是继续访问被请求的网站。

Screenshot showing the certificate authorities trusted by a web browser

您可以使用 openssl 命令生成证书签名请求。我们使用了以下选项:

  • req -new 创建新的证书签名请求
  • -nodes 保存不带密码的私钥
  • -newkey 生成新的私钥
  • rsa:4096 生成长度为4096位的RSA密钥
  • -keyout 指定保存密钥的位置
  • -out 保存证书签名请求

然后你将被要求回答一系列问题,如下面的控制台输出所示。

user@TryHackMe$ openssl req -new -nodes -newkey rsa:4096 -keyout key.pem -out cert.csr
[...]
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:UK
State or Province Name (full name) []:London
Locality Name (eg, city) [Default City]:London
[...]

一旦CSR文件准备好了,你就可以把它发送给你选择的CA,对它进行签名,以便在你的服务器上使用。

一旦客户端(即浏览器)收到它信任的签名证书,SSL/TLS握手就开始了。目的是就密码和密钥达成一致。

我们刚刚描述了PKI(公钥基础设施)如何应用于web和SSL/TLS证书。可信第三方是系统可扩展的必要条件。

为了测试,我们创建了一个自签名证书。例如,下面的命令将生成自签名证书。

openssl req -x509 -newkey -nodes rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365

-x509 表示我们想生成的是自签名证书,而不是证书请求。 -sha256 指定SHA-256摘要的使用。因为我们增加了 -days 365 ,所以有效期为一年。

您需要检查 task06 目录下的证书文件 cert.pem 。你可以使用以下命令查看证书:

openssl x509 -in cert.pem -text

问题

1.公钥的位数是多少?

2.这张证书有效期到哪一年?

WP

1、2.使用以下命令查看证书:

openssl x509 -in cert.pem -text

image-20240718205715761

image-20240718205740436

使用密码进行身份验证

让我们看看密码学是如何帮助提高密码安全性的。通过PKI和SSL/TLS,我们可以与任何服务器通信,并提供我们的登录凭据,同时确保在网络上传输密码时没有人可以读取我们的密码。这是一个保护传输数据的例子。让我们来探索如何保护保存在数据库中的密码,即静止的数据。

最不安全的方法是将用户名和密码保存在数据库中。这样,任何数据泄露都会暴露用户的密码。除了读取包含密码的数据库外,不需要做任何工作。

用户名 密码
alice qwerty
bob dragon
charlie princess

改进的方法是将用户名和密码的散列值保存在数据库中。通过这种方式,数据泄露将暴露密码的哈希版本。由于哈希函数是不可逆的,攻击者需要不断尝试不同的密码,才能找到能得到相同哈希值的密码。下表显示了密码的MD5值。(我们选择MD5只是为了让密码字段较小;否则,我们会使用SHA256或其他更安全的方法。)

用户名 散列(密码)
alice d8578edf8458ce06fbc5bb76a58c5ca4
bob 8621ffdbc5698829397d97767ac13db3
charlie 8afa847f50a716e64932d995c8e7435a

前面的方法看起来是安全的;然而,彩虹表的可用性使得这种方法不安全。rainbow表包含密码及其散列值的列表。因此,攻击者只需要查找哈希值就可以恢复密码。例如,通过查找 d8578edf8458ce06fbc5bb76a58c5ca4 ,可以很容易地发现 alice 的原始密码。因此,我们需要找到更安全的方法来安全地保存密码;我们可以加盐。salt是一个随机值,我们可以在对密码进行哈希运算之前将其添加到密码后面。下面给出了一个例子。

用户名 密码散列(盐)
alice 8a43db01d06107fcad32f0bcfa651f2f 12742
bob aab2b680e6a1cb43c79180b3d1a38beb 22861
charlie 3a40d108a068cdc8e7951b82d312129b 16056

上表使用 hash(password + salt) ;另一种方法是使用 hash(hash(password) + salt) 。注意,我们在使用MD5散列函数时使用了相对较小的salt值。如果这是一个实际的设置,我们应该切换到一个(更)安全的散列函数和一个大的盐值,以获得更好的安全性。

在保存密码之前,我们可以做的另一个改进是使用密钥推导函数,如PBKDF2 (password - based key推导function 2)。PBKDF2获取密码和盐,并通过一定的迭代次数(通常为数十万次)提交它。

如果您想了解与密码存储相关的其他技术,我们建议您检查密码存储备忘单。

问题

您在审计一个系统时,发现admin密码的MD5散列值是 3fc0a7acf087f549ac2b266baf94b8b1 。原始密码是什么?

WP

随便找一个MD5解密网站解密即可:

image-20240718205922932

image-20240718205949820

密码学和数据-示例

在此任务中,我们想探索通过HTTPS登录网站时会发生什么。

  1. 客户端请求服务器的 SSL/TLS 证书
  2. 服务器向客户端发送 SSL/TLS 证书
  3. 客户端确认证书有效

加密的作用从检查证书开始。要使证书被视为有效,则意味着它已签名。签名意味着证书的哈希值使用受信任的第三方的私钥进行加密;加密的哈希将追加到证书中。

如果第三方是可信的,客户端将使用第三方的公钥来解密加密的哈希,并将其与证书的哈希进行比较。但是,如果无法识别第三方,则连接将不会自动进行。

客户端确认证书有效后,将启动 SSL/TLS 握手。这种握手允许客户端和服务器就密钥和对称加密算法等达成一致。从现在开始,所有相关的会话通信都将使用对称加密进行加密。

最后一步是提供登录凭据。客户端使用加密的 SSL/TLS 会话将它们发送到服务器。服务器收到用户名和密码,需要确认它们是否匹配。

根据安全准则,我们希望服务器在向其附加随机盐后保存密码的哈希版本。这样,如果数据库被破坏,密码将难以恢复。

结论

密码学是一个庞大的话题。在这个房间里,我们试图把重点放在核心概念上,这些概念可以帮助你理解密码学中常用的术语。这些知识对于理解使用加密和散列的系统的配置选项至关重要。

posted @ 2024-07-18 21:04  Super_Snow_Sword  阅读(27)  评论(0编辑  收藏  举报