Shell脚本中实现密码加密的正确方案是什么?
密码加密存储优化方案
首先需要明确前提:由于用户是服务器所有者,持有服务器最高权限,不存在100%完全避免用户获取真实密码的方案,以下方案均为大幅提升用户获取密码的门槛,满足绝大多数场景的防护需求。
方案1:移除脚本内硬编码解密密钥
不要将解密密钥明文写在脚本中,改为通过服务器独有硬件特征动态生成解密密钥,仅当前服务器环境可以生成正确的解密密钥,用户将脚本和加密文件复制到其他设备无法解密,示例逻辑如下:
# 读取CPU序列号(需root权限) CPU_SN=$(dmidecode -t processor | grep 'ID' | head -n 1 | awk '{print $2$3$4$5$6$7$8$9}') # 读取根目录所在硬盘UUID DISK_UUID=$(blkid $(df / | grep / | awk '{print $1}') | grep -o 'UUID="[^"]*"' | awk -F '"' '{print $2}') # 拼接生成解密密钥 DECRYPT_KEY=$(echo "${CPU_SN}${DISK_UUID}" | md5sum | awk '{print $1}') # 解密密码 var=$(cat secret.txt | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:${DECRYPT_KEY})
方案2:通过系统密钥环存储敏感信息
使用系统原生的密钥管理服务存储解密密钥或真实密码,避免敏感信息出现在脚本或明文文件中:
- Linux环境可使用
libsecret对应的secret-tool命令操作密钥环,提前将密码存入密钥环后,脚本仅需调用命令读取即可 - 密钥环本身支持独立密码加密,且读写权限与用户会话绑定,大幅降低敏感信息泄露风险
示例代码片段:
# 提前执行一次存入密码:secret-tool store --label='tabcmd_password' service tabcmd username adm # 脚本中读取密码 var=$(secret-tool lookup service tabcmd username adm)
方案3:将Shell脚本编译为二进制可执行文件
使用shc工具将Shell脚本转换为二进制程序,避免用户直接查看脚本内容、修改脚本添加打印语句获取密码:
- 安装shc工具后执行
shc -f your_script.sh,生成后缀为.sh.x的二进制可执行文件 - 将原脚本、加密后的secret.txt权限设置为仅root可读写,给二进制文件添加SUID权限,用户直接执行二进制文件即可完成操作
- 普通用户无法直接逆向二进制文件获取内部的密钥或逻辑,防护效果较好
额外优化建议
- 脚本中使用完密码变量后立即执行
unset var,减少密码明文在内存中的留存时间 - 避免任何场景下将密码变量输出到日志、终端等位置
内容的提问来源于stack exchange,提问作者Djabone
相关产品推荐
相关产品推荐

