密码学中的对称加密基础

LinuxBeginner
立即练习

介绍

对称加密(Symmetric encryption)是密码学中的一个基本概念,它使用同一个密钥来加密和解密信息。这种方法快速且高效,非常适合加密大量数据。

在这个 Lab 中,你将使用 Linux 环境中强大的 openssl 命令行工具,亲手实践对称加密。你将完成整个流程:生成一个密钥(secret key),加密一个文本文件,解密该文件,最后验证解密后的文件与原始文件完全一致。

对称加密概念

在这一步,我们将简要回顾对称加密的核心概念。“对称”的含义是,用于锁定(加密)数据的同一个密钥,也用于解锁(解密)数据。

想象你有一个物理的锁箱。你用一把钥匙把它锁上。要再次打开它,你必须使用完全相同的钥匙。在对称加密中,这个密钥是一段数字信息,它必须在需要加密和解密数据的各方之间安全共享。如果这个唯一的密钥泄露,加密数据的安全性就丧失了。

对于这个 Lab,我们将处理一个简单的文本文件。一个名为 original.txt 的文件已经为你预先创建在 ~/project 目录下。你可以查看它的内容,确认它是一个纯文本、可读的文件。

让我们列出当前目录中的文件,看看它:

ls -l

你应该在输出中看到 original.txt 文件:

-rw-rw-r-- 1 labex labex 26 Oct 20 08:56 original.txt

现在,让我们查看它的内容:

cat original.txt

输出将是文件内部的简单文本消息:

This is a secret message.

在接下来的步骤中,我们将加密这个文件使其不可读,然后将其解密回原始形式。

生成 AES 密钥

在这一步,你将为我们的加密过程生成一个安全的、随机的密钥。对称加密的强度在很大程度上依赖于密钥的保密性和随机性。一个可预测的密钥很容易被猜到,从而使加密失效。

我们将使用 openssl rand 命令来生成一个密码学上安全的随机密钥。我们将生成一个 256 位(bit)的密钥,这是 AES(Advanced Encryption Standard,高级加密标准)算法的标准长度。

执行以下命令来生成 32 字节(256 位)的随机数据,并以十六进制(hexadecimal)格式保存到名为 aes.key 的文件中:

openssl rand -hex 32 > aes.key

我们来解析一下这个命令:

  • openssl rand: 用于生成随机数据的命令。
  • -hex: 将输出格式化为十六进制字符串。
  • 32: 指定要生成的随机数据的字节数。由于每个十六进制字符代表 4 位(或半个字节),32 字节的数据将生成一个 64 个字符的十六进制字符串。
  • > aes.key: 将命令的输出重定向并保存到 aes.key 文件中。

现在,让我们查看生成的密钥。请记住,由于密钥是随机生成的,你的密钥将与下面的示例不同。

cat aes.key

你将看到一长串十六进制字符,这就是你的 256 位密钥:

2da75d4f284618ed6933d0e743757ed014ba39a1a8aa1879ebbbfe53b92d519a

现在,文件 aes.key 中保存着我们将用于加密和解密数据的密钥。

使用 AES 加密文件

在这一步,你将使用生成的密钥来加密 original.txt 文件。我们将使用 openssl enc 命令,这是一个多功能的加密和解密工具。

我们将使用 AES-256-CBC 密码(cipher)。

  • AES-256: 指使用 256 位密钥的高级加密标准。
  • CBC: 代表 Cipher Block Chaining(密文分组链接),这是一种操作模式,它增加了随机性,并确保相同的明文分组不会产生相同的密文分组。

运行以下命令来加密文件:

openssl enc -aes-256-cbc -pbkdf2 -salt -in original.txt -out encrypted.dat -pass file:./aes.key

我们来分析一下命令选项:

  • openssl enc: 用于加密密码的命令。
  • -aes-256-cbc: 指定要使用的加密算法。
  • -pbkdf2: 使用基于标准的现代密码派生函数(PBKDF2)来防止弃用警告。
  • -salt: 在加密前向密钥添加一个随机盐(salt)。这是防止某些类型攻击的关键安全实践。
  • -in original.txt: 指定要加密的输入文件。
  • -out encrypted.dat: 指定将存储加密数据输出文件的名称。
  • -pass file:./aes.key: 告诉 OpenSSL 从 aes.key 文件中读取密码(在我们的例子中是密钥)。

运行命令后,会创建一个名为 encrypted.dat 的新文件。让我们尝试查看它的内容:

cat encrypted.dat

输出将是一堆不可读的字符,证实文件已被加密。

Salted___Mi72j)NU_nJ_h9s(0]%

你现在已经成功加密了你的秘密消息。任何在没有 aes.key 的情况下获得此文件的人都将无法读取其内容。

使用 AES 解密文件

在这一步,你将解密 encrypted.dat 文件以恢复原始消息。由于这是对称加密,我们将使用与加密时相同的密钥(aes.key)和相同的基本命令(openssl enc)。

关键的区别是添加了 -d 标志,它告诉 OpenSSL 执行解密而不是加密。

执行以下命令来解密文件:

openssl enc -d -aes-256-cbc -pbkdf2 -in encrypted.dat -out decrypted.txt -pass file:./aes.key

此命令与加密命令非常相似:

  • -d: 此标志指定我们想要解密输入文件。
  • -aes-256-cbc: 我们必须指定与加密时使用的相同密码(cipher)。
  • -pbkdf2: 你必须使用与加密时相同的密钥派生函数。
  • -in encrypted.dat: 输入文件现在是我们的加密数据。
  • -out decrypted.txt: 将保存解密后的、可读文本的输出文件。
  • -pass file:./aes.key: 我们提供用于加密文件的相同密钥。

命令完成后,将创建一个名为 decrypted.txt 的新文件。让我们查看其内容,以确认解密是否成功。

cat decrypted.txt

输出应该是原始消息,与 original.txt 中的内容完全一致:

This is a secret message.

恭喜!你已经成功完成了一次完整的加密和解密循环。

验证文件完整性

在最后一步中,我们将验证解密过程是完美的,并且 decrypted.txt 文件是 original.txt 文件的精确副本。虽然我们可以通过目视检查确认短消息是否一致,但对于更大的文件或自动化脚本来说,进行程序化检查是必要的。

Linux 中的 diff 命令是完成此任务的完美工具。它逐行比较两个文件并报告任何差异。如果文件相同,diff 将不会产生任何输出。

运行 diff 命令来比较原始文件和解密文件:

diff original.txt decrypted.txt

如果命令运行后,你返回到命令行提示符而没有任何消息,这意味着文件是相同的。这种静默就是成功的确认。它证明了你的数据在整个加密和解密周期中都保持了其完整性。

要查看你在本次实验中处理过的所有文件,你可以再运行一次 ls -l

ls -l

你将看到原始文件、密钥、加密数据和最终的解密文件:

-rw-rw-r-- 1 labex labex 65 Oct 20 08:57 aes.key
-rw-rw-r-- 1 labex labex 26 Oct 20 08:57 decrypted.txt
-rw-rw-r-- 1 labex labex 48 Oct 20 08:57 encrypted.dat
-rw-rw-r-- 1 labex labex 26 Oct 20 08:56 original.txt

这证明你已经成功管理了对称加密的整个生命周期。

总结

在本次实验中,你学习了在 Linux 环境中使用 openssl 进行对称加密的基础知识,并获得了实践经验。

你成功地执行了一个完整的加密和解密工作流程:

  • 你学习了使用单个共享密钥进行加密和解密的核心概念。
  • 你使用了 openssl rand 来生成一个强大的 256 位 AES 密钥。
  • 你使用 openssl enc 加密了一个文本文件,使其内容无法读取。
  • 你使用了带有 -d 标志的相同命令,将文件解密回其原始状态。
  • 最后,你使用 diff 命令以编程方式验证了解密后的数据与原始数据完全相同,从而确认了数据完整性。

这个动手练习为你理解对称密码(symmetric ciphers)的工作原理及其在实践中如何应用于保护数据,奠定了坚实的基础。