密码技术应用实验—AES 对称加密与口令安全初体验

一、 概述

|------------|---------------------------------------------------|
| 项目 | 说明 |
| 实验名称 | 给压缩包上锁------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 位以上、含大小写数字符号的强口令,并通过其他渠道单独告知对方。 |

相关推荐
xixiaoyunya2 小时前
只备份数据远远不够:服务器系统备份的完整方案与实践
服务器·网络·数据库
jimmyleeee2 小时前
大模型安全之七:LLM系统提示词泄露
人工智能·安全
淡淡的香烟2 小时前
AndroidKMP之网络请求
android·网络
是隼人3 小时前
buuctf-pwn jarvisoj_level5(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
筝筝ba3 小时前
OpenBMC 自动化测试中的多进程陷阱:从 Execute Process 返回异常到 output.xml 损坏问题分析
xml·linux·运维·服务器·网络
2601_966377133 小时前
运营商密评密改落地实践:透明加密解决密码应用合规与安全痛点
数据库·安全·oracle
可乐鸡翅yeah_3 小时前
M3U8测试流使用指南,流媒体开发自测与环境校验标准化方案
网络·ffmpeg·音视频·m3u8·m3u8在线·音视频在线播放
孤狼warrior3 小时前
SCTR 五次失败的安全 BN 路由器
人工智能·python·深度学习·算法·安全·yolo
闲云野鹤在人间3 小时前
云计算入门|网络与存储云服务知识梳理
linux·运维·服务器·网络·centos·云计算·php