You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python脚本隐藏凭据最优方法及PyInstaller打包安全性问询

嘿,这个问题问到点子上了——明文存储凭据绝对是安全大忌,我来给你分享几个生产环境里常用的安全方案,顺便解答你关于PyInstaller的疑问:

一、Python脚本中隐藏凭据的最佳方法

1. 使用环境变量(最便捷的无代码硬编码方案)

把服务器地址和密码存在系统环境变量里,脚本通过os.getenv()读取,完全避免硬编码。

示例代码:

import paramiko
import os

# 从环境变量读取凭据
my_server = os.getenv('SSH_TARGET_SERVER')
my_password = os.getenv('SSH_ROOT_PASSWORD')

ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    ssh.connect(my_server, username='root', password=my_password)
except paramiko.SSHException:
    print("Connection Failed")
    quit()
  • 设置方式:Windows用setx SSH_TARGET_SERVER "myserver",Linux/macOS用export SSH_TARGET_SERVER=myserver(永久生效需要写入bashrc/zshrc或系统配置文件)。

2. 加密配置文件(适合需要持久化存储的场景)

如果必须把凭据存在文件里,一定要加密,不能用明文。推荐用cryptography库实现对称加密:

第一步:生成密钥并加密凭据(只执行一次)

from cryptography.fernet import Fernet

# 生成加密密钥,务必妥善保管(别和脚本/打包后的exe放一起)
key = Fernet.generate_key()
with open('secret.key', 'wb') as key_file:
    key_file.write(key)

# 加密服务器地址和密码
cipher = Fernet(key)
encrypted_server = cipher.encrypt(b'myserver')
encrypted_password = cipher.encrypt(b'mysecret')

# 保存加密后的内容
with open('credentials.enc', 'wb') as enc_file:
    enc_file.write(encrypted_server + b'\n' + encrypted_password)

第二步:脚本中解密读取凭据

import paramiko
from cryptography.fernet import Fernet

# 加载密钥(注意密钥要单独存放,比如加密存储在本地或者由用户手动输入)
with open('secret.key', 'rb') as key_file:
    key = key_file.read()
cipher = Fernet(key)

# 读取并解密
with open('credentials.enc', 'rb') as enc_file:
    encrypted_server = enc_file.readline().strip()
    encrypted_password = enc_file.readline().strip()

my_server = cipher.decrypt(encrypted_server).decode()
my_password = cipher.decrypt(encrypted_password).decode()

# 后续连接逻辑不变
ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    ssh.connect(my_server, username='root', password=my_password)
except paramiko.SSHException:
    print("Connection Failed")
    quit()

3. SSH密钥认证(最安全的SSH连接方式)

完全抛弃密码,用SSH密钥对认证:

  1. 生成本地密钥对(ssh-keygen命令,可设置密钥密码);
  2. 将公钥上传到服务器的~/.ssh/authorized_keys文件中;
  3. 脚本中用私钥连接:
import paramiko
from getpass import getpass

ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    # 如果私钥设置了密码,用getpass交互式输入,避免硬编码
    passphrase = getpass("Enter private key passphrase (if set): ")
    ssh.connect(
        'myserver', 
        username='root', 
        key_filename='/path/to/your/private_key',
        passphrase=passphrase
    )
except paramiko.SSHException:
    print("Connection Failed")
    quit()

这种方式就算私钥泄露,没有密码也无法使用,安全性拉满。

4. 交互式输入(适合手动触发的脚本)

如果脚本不需要自动化运行,用getpass模块让用户手动输入凭据,完全不存储:

import paramiko
from getpass import getpass

my_server = input("Enter target server address: ")
my_password = getpass("Enter root password: ")

ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    ssh.connect(my_server, username='root', password=my_password)
except paramiko.SSHException:
    print("Connection Failed")
    quit()

二、PyInstaller打包后是否能被反汇编拿到明文?

答案是肯定的。PyInstaller只是把Python脚本、依赖库和解释器打包成一个可执行文件,内部包含的是编译后的Python字节码(.pyc格式)。而字节码非常容易被反编译回近似原始的Python代码,甚至用strings命令直接扫描exe文件,就能提取出硬编码的明文凭据。

所以绝对不能把明文凭据硬编码在脚本里再打包,一定要用上面提到的安全方案替代。

内容的提问来源于stack exchange,提问作者DDBE

火山引擎 最新活动