一、 概述
|------------|---------------------------------------------------|
| 项目 | 说明 |
| 实验名称 | 给压缩包上锁------AES 对称加密初体验 |
| 实验平台 | 天枢一体化虚拟仿真平台 |
| 终端环境 | openEuler 24.03 |
| 核心命令 | openssl enc、xxd、md5sum、diff、zip、7z |
| 核心算法 | AES-256-CBC(国际对称算法)、SM4-CBC(国密对称算法)、PBKDF2 密钥派生 |

二、实验目的
- 理解对称加密的核心思想------"一把钥匙开一把锁" :加密和解密使用同一个密钥;
- 观察明文与密文的差异,体会****"没有密钥就是一堆乱码"**** 的直观感受;
- 亲手验证密钥敏感性 :口令错一个字符,解密就会失败;
- 学会用 OpenSSL 完成 AES-256-CBC 加解密,并会用 zip / 7z 给压缩包设置安全口令;
- 引出密钥分发难题 :密钥怎么安全地告诉对方?为后续非对称加密实验埋下伏笔。
三、实验原理(对称加密与 AES)
对称加密 : 加密和解密使用同一个密钥 。AES(高级加密标准)是目前最主流的对称分组密码:本实验使用 AES-256,即密钥长度 256 位;CBC 是分组工作模式,按 16 字节一组加密,最后不足一组用 PKCS#7 填充。
OpenSSL enc : OpenSSL 是 openEuler 默认集成的密码学工具集,openssl enc 子命令专门做对称加解密。-a 把密文做 Base64 编码,变成可复制粘贴的文本;-salt 加入随机盐;-pass pass:口令 指定密钥。
盐(Salt) : 加密时随机生成 8 字节盐,密文以 Salted__ 开头记录它。同样的口令、同样的文件,每次加密出的密文都不同------攻击者无法预先把"常见口令的密文"做成对照表(彩虹表)。
PBKDF2 密钥派生 : 口令本身不是密钥。OpenSSL 用密钥派生函数(KDF)从"口令 + 盐"算出真正的加密密钥。OpenSSL 3.x 推荐使用 -pbkdf2 参数(基于口令的密钥派生标准,多轮迭代、暴力破解成本高);不加该参数会使用老式派生算法并给出 deprecated 警告。
国密 SM4 : SM4 是我国商用密码标准中的分组对称算法(GB/T 32907),分组和密钥长度均为 128 位。OpenSSL 3.0+ 内置支持,命令写法与 AES 完全一致,只需把算法名换成 -sm4-cbc。
压缩包口令的真相 : zip / 7z 的"解压密码"本质上还是对称加密:口令就是密钥。需要特别注意:传统 zip 口令使用 ZipCrypto 算法(1990 年代设计),强度弱、已有成熟破解手段;7z / WinRAR 的 AES-256 才是强加密;7z 加 -mhe=on 后连压缩包内的文件名都会一起加密。
密钥分发难题 : 对称加密有一个绕不开的死结:接收方必须拿到同一个密钥才能解密,但密钥本身也需要安全传输------这就是"密钥分发问题",本实验最后会讨论它。
四、实验环境准备(openEuler 24.03)
4.1 确认系统与 OpenSSL 版本
|---------------------------------------------------------------------------------------------------------------------|
| cat /etc/os-release | head -3 uname -r openssl version |
| 预期输出(类似) NAME="openEuler" VERSION="24.03 LTS" OpenSSL 3.0.x ... |
| ****说明:****openEuler 24.03 LTS 于 2024 年 6 月发布,默认内核为 6.6(本实验不挑内核版本,5.10 及以上均可),内置 OpenSSL 3.0+,已支持 AES 与 SM4 全套对称算法。 |
4.2 检查并安装实验工具
|-------------------------------------------------------------------------------------------------------------|
| # 检查工具是否齐全 which openssl xxd zip 7z # openEuler 安装缺失工具(yum 与 dnf 完全等价) dnf install openssl vim zip p7zip -y |
| 提示 xxd 十六进制查看工具在 openEuler 中位于 vim-common 软件包;7z 命令由 p7zip提供。主实验(OpenSSL 部分)不依赖 zip/7z,第六章压缩包实战才需要。 |
4.3 创建实验目录与明文文件
|------------------------------------------------------------------------------------------------------------------------------------------|
| mkdir -p ~/crypto_lab cd ~/crypto_lab # 创建一个包含敏感信息的明文文件 echo "我的银行卡号是 6222 8888 6666 1234" > bank_card.txt # 查看文件内容 cat bank_card.txt |
| 预期输出 我的银行卡号是 6222 8888 6666 1234 |
五、实验步骤
步骤 1 · 观察明文
加密之前,先看看原始文件的样子------任何人拿到都能直接读懂:
|--------------------------------------------------------------------------------------------------------------|
| # 查看文件内容(明文) cat bank_card.txt # 查看文件的十六进制表示 xxd bank_card.txt |
| 预期输出(xxd 部分)
|
| 结论 文件是可直接阅读的明文 ,共 42 字节(UTF-8 编码下每个汉字占 3 字节),末尾的 0a 是 echo 自动追加的换行符。这样的文件在网络上被截获,银行卡号就直接泄露了。 |
步骤 2 · 上锁:AES-256 加密
2.1 执行加密(发送方小明操作):
|---------------------------------------------------------------------------------------------------------------------------------------------------|
| # AES-256-CBC 加密(随机盐 + PBKDF2 派生 + Base64 编码) openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass pass:mykey2026 -in bank_card.txt -out bank_card.enc |
2.2 命令参数说明:
|----------------------|------------------------------------|
| 参数 | 含义 |
| enc | 调用 OpenSSL 的对称加密 / 解密功能 |
| -aes-256-cbc | 使用 AES-256 算法、CBC 分组模式 |
| -a | 对密文做 Base64 编码,输出为可复制粘贴的文本 |
| -salt | 加入随机盐:相同口令每次加密得到不同密文,防彩虹表 |
| -pbkdf2 | 用 PBKDF2 从口令派生密钥(OpenSSL 3.x 推荐用法) |
| -pass pass:mykey2026 | 指定口令(即对称密钥)为 mykey2026 |
| -in / -out | 输入明文文件 / 输出密文文件 |
| -d | 解密模式(本步骤不用,步骤 3、4 使用) |
2.3 观察密文:
|-----------------------------------------------------------------------------------------------------------|
| cat bank_card.enc |
| 预期输出(某次真实运行结果,每次加密都不同)
|
密文变成了完全不可读的乱码。开头的 U2FsdGVkX1 是 Base64 文本特征,解码后能看到 8 字节的"Salted__"文件头:
|-----------------------------------------------------------------------------------------|
| # 密文 Base64 解码后查看字节头 base64 -d bank_card.enc | xxd | head -2 |
| 预期输出
|
2.4 对比明文与密文大小:
|----------------------------------------------------------------------------------------------------------------|
| ls -l bank_card.txt bank_card.enc |
| 预期输出(类似)
|
| 结论 明文 42 字节,密文 90 字节。变大有三个原因:① Salted__ 文件头 + 8 字节随机盐;② CBC 分组填充(不足 16 字节的倍数要补齐);③ Base64 编码体积膨胀约 1/3。 |
2.5 验证随机盐:用同一口令连续加密两次,对比密文:
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass pass:mykey2026 -in bank_card.txt -out c1.enc openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass pass:mykey2026 -in bank_card.txt -out c2.enc diff c1.enc c2.enc && echo "两次密文相同" || echo "两次密文不同(随机盐生效)" |
| 预期输出
|
即使文件和口令完全相同,两次密文也毫无共同之处------预计算对照表的攻击方式就此失效。
步骤 3 · 错误钥匙:验证密钥敏感性
对称加密的重要特性:密钥错一点都解不开。接收方小红如果把口令 mykey2026 错输成 mykey2025:
|-------------------------------------------------------------------------------------------------------------------------------|
| # 用错误口令 mykey2025 尝试解密 openssl enc -d -aes-256-cbc -a -pbkdf2 -pass pass:mykey2025 -in bank_card.enc -out bank_card_wrong.txt |
| 预期输出(命令报错,退出码非 0)
|
即使生成了输出文件,内容也是随机乱码:
|-------------------------------------------------------------------------------------------------------------|
| # 查看错误解密的"结果" xxd bank_card_wrong.txt 2>/dev/null | head -2 |
| 核心结论 解密时 OpenSSL 用口令派生出密钥去解密,密钥不同 → 解密出的字节不同 → 填充校验失败 → 报 bad decrypt 。口令就是唯一的钥匙,错一个字符都打不开。 |
步骤 4 · 正确解锁:解密并验证完整性
4.1 用正确口令解密(接收方小红操作):
|---------------------------------------------------------------------------------------------------------------------------------|
| # 用正确口令 mykey2026 解密 openssl enc -d -aes-256-cbc -a -pbkdf2 -pass pass:mykey2026 -in bank_card.enc -out bank_card_decrypted.txt |
4.2 验证解密结果:
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 查看还原内容 cat bank_card_decrypted.txt # 逐字节比对两个文件(无输出且打印提示 = 完全一致) diff bank_card.txt bank_card_decrypted.txt && echo "文件完全一致" # 计算并对比 MD5 哈希值 md5sum bank_card.txt bank_card_decrypted.txt |
| 预期输出
|
| 注意 : 解密时算法与参数必须与加密时完全一致 :算法名、-a、-pbkdf2 一个都不能少或不一致,否则都会报 bad decrypt。两个文件 MD5 相同,证明解密还原没有任何数据损坏。 |
步骤 5 · 明文与密文特征对比
|-------------|--------------------------|---------------------------|
| 对比项 | 明文 bank_card.txt | 密文 bank_card.enc |
| 可读性 | 直接可读,银行卡号一目了然 | Base64 乱码,解码后仍是随机字节 |
| 文件大小 | 42 字节 | 90 字节(盐 + 填充 + Base64 膨胀) |
| 内容规律性 | UTF-8 汉字 + 数字,结构清晰 | 随机分布字节,无任何可读信息 |
| 拿到文件能否读懂 | 任何人都能读懂 | 只有持正确口令者能解密 |
这正是加密的意义:文件可以被任何人截获,但内容只对持有密钥的人可见。
步骤 6 · 国密对照:SM4-CBC 加解密
把算法从 AES-256 换成我国商用密码标准 SM4,命令写法完全相同:
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # SM4-CBC 加密(国密对称算法) openssl enc -sm4-cbc -a -salt -pbkdf2 \ -pass pass:mykey2026 -in bank_card.txt -out bank_card_sm4.enc # SM4-CBC 解密 openssl enc -d -sm4-cbc -a -pbkdf2 \ -pass pass:mykey2026 -in bank_card_sm4.enc -out bank_card_sm4.dec # 验证还原一致 diff bank_card.txt bank_card_sm4.dec && echo "SM4 加解密一致" |
| 预期输出 SM4 加解密一致 |
| 结论 AES 与 SM4 只是"锁"的品牌不同,对称加密的原理和操作完全一致 。在国产化环境中,可直接使用 SM4 替代 AES 满足合规要求。可用 openssl enc -list | grep sm4 查看本机支持的全部 SM4 模式(cbc / cfb / ctr / ecb / ofb)。 |
步骤 7 · 密钥传递难题(核心讨论)
文件成功加密、成功解密,但一个关键问题浮出水面:小明要怎么把密钥 mykey2026 安全地告诉小红?
常见传递方式的风险:
|--------------|-------------------------------|
| 传递方式 | 风险 |
| 微信 / QQ 发送 | 消息可能被第三方截获或监听;密钥和密文走同一渠道等于没上锁 |
| 电子邮件 | 邮件在传输和投递过程中可能被中间人截取 |
| 电话 / 短信告知 | 通话与短信同样可能被窃听、截留 |
| 当面告知 | 最安全,但两人异地时无法实现 |
问题的本质是对称加密的死循环:
|--------------------------------------------------------|
| 要安全传文件 → 需要加密 → 需要密钥 → 要安全传密钥 → 又需要加密 → 又需要另一个密钥 → ... |
这在密码学中称为"密钥分发问题"(Key Distribution Problem)。现实中的解决方案:
- 面对面交换 :最安全,但不适用于远程场景;
- Diffie-Hellman 密钥交换 :双方在不安全信道上协商出共享密钥;
- 非对称加密(公钥加密) :用对方公钥加密密钥,只有对方私钥能解密------这正是后续实验要探索的内容;
- 密钥分发中心(KDC) :由可信第三方统一管理密钥分发。
|---------------------------------------------------------------------------|
| 预告 在后续非对称加密实验中,小明可以用小红的公钥加密密钥,只有小红的私钥能解密------密钥不需要事先秘密传递,死循环被打破。 |
六、压缩包加密实战:zip / 7z 上锁
回到实验标题:日常工作中最常见的"给压缩包上锁",就是对称加密的直接应用。以下三种方式安全性不同,请按场景选择。
6.1 传统 zip 口令(ZipCrypto,弱加密)
|---------------------------------------------------------------------------------------------------------------------|
| # 加密:-r 递归打包,-e 设置口令(回车后按提示输入两次口令) zip -re secret.zip bank_card.txt # 解压(按提示输入口令) unzip secret.zip |
| 安全提醒 zip 的传统口令使用 ZipCrypto 算法,强度弱 ,已有成熟的已知明文攻击工具;且它没有完整性校验 ,输错口令有时不报错、只解压出乱码。重要文件不要只依赖这种方式。 |
6.2 7z 创建 AES-256 强加密(推荐)
|---------------|----------------------------------|
| # 加密:AES-256 + 头部加密(连文件名都看不到) 7za a -p'mykey2026' -mhe=on secret.7z bank_card.txt # 解压(回车后输入口令) 7za x secret.7z ||
| 参数 | 含义 |
| a | 新建 / 更新压缩包 |
| -p'mykey2026' | 设置口令(-p 与口令之间没有空格;不加口令则交互输入) |
| -mhe=on | 头部加密:压缩包内文件名、大小等信息也加密(仅 7z 格式支持) |
| 默认加密算法 | 7z 格式默认即 AES-256 + SHA-256,属于强加密 |
6.3 生成 AES-256 加密的 .zip(兼容 WinRAR / WinZip)
如果对方要求必须是 .zip 后缀,可用 7z 生成 AES-256 加密的 zip(WinRAR、WinZip、Bandizip 均可正常打开):
|-------------------------------------------------------------------------------------------------------------------------------------|
| 7za a -tzip -p'mykey2026' -mem=AES256 secret_aes.zip bank_card.txt 7za x secret_aes.zip |
| 错误口令的现象 7z 口令错误时报 ERROR: Wrong password 并以退出码 2 终止;传统 zip 口令错误时提示 password incorrect--reenter,或解压出乱码文件。 |
| 结论 压缩包口令本质就是对称加密的密钥 ,同样逃不开密钥分发难题;而且口令强度决定一切------mykey2026 这类字典词在破解软件面前秒破,实际使用应设 12 位以上、含大小写数字符号的强口令,并通过其他渠道单独告知对方。 |