影刀RPA 密码安全管理:凭证加密存储与安全调用 影刀RPA 密码安全管理凭证加密存储与安全调用作者林焱什么情况用写自动化流程的时候你不可避免地要把各种密码和Token写在某个地方登录网站要用账号密码调用API要用API Key连数据库要用数据库密码发邮件要用邮箱授权码如果你把这些硬编码在流程里导出分享给别人——密码就跟着走了。更糟糕的是影刀支持云端存储流程你把凭证明文写到代码里就上传云端了。核心场景流程中需要用到密码/Token但不能明文写在代码里。怎么做第一步分清安全等级不是所有凭证都需要同等级的保护拼多多店群自动化上架方案安全等级内容存储方案低测试环境账号、非敏感API Key影刀全局变量中公司内部系统密码、邮件密码AES本地加密文件| 高 | 生产数据库密码、支付密钥 | 密钥管理服务/Windows凭据管理器 |第二步利用影刀全局变量适合低敏感度影刀支持设置全局变量不会导出到分享的流程文件中。打开影刀客户端 → 左侧「全局变量」新增变量比如DB_PASSWORD值填密码在Python节点中读取# 影刀全局变量会自动注入到Python节点passwordDB_PASSWORDprint(f连接数据库密码长度为{len(password)}位)# 不要打印密码本身局限变量值在影刀服务端明文存储不适合真正的敏感信息。所以这只适合测试环境。第三步AES本地加密存储适合中等敏感度核心思路密码加密后存到本地文件用的时候解密用完不残留。importosimportjsonimportbase64fromcryptography.fernetimportFernetfromcryptography.hazmat.primitivesimporthashesfromcryptography.hazmat.primitives.kdf.pbkdf2importPBKDF2HMACclassSecureCredentialManager: 凭证安全管理器 基于AES-256加密主密码盐值派生密钥 def__init__(self,vault_pathcredentials.enc,master_passwordNone): vault_path: 加密凭证文件路径 master_password: 主密码不存盘每次运行输入 self.vault_pathvault_path# 主密码不存盘如果没提供就尝试从环境变量读取ifmaster_passwordisNone:master_passwordos.environ.get(RPA_MASTER_KEY,default-dev-key)# 从主密码派生加密密钥self.cipherself._derive_key(master_password)def_derive_key(self,master_password):从主密码派生AES密钥saltbyingdao_rpa_2024# 固定盐值生产环境换成随机值kdfPBKDF2HMAC(algorithmhashes.SHA256(),length32,# 256位saltsalt,iterations480000,# 迭代次数越高越安全但也越慢)keybase64.urlsafe_b64encode(kdf.derive(master_password.encode()))returnFernet(key)defstore_credential(self,service_name,username,password,metadataNone):存储一个凭证加密后写文件# 读取现有凭证vaultself._read_vault()# 加密密码encrypted_pwdself.cipher.encrypt(password.encode()).decode()# 存入vault[service_name]{username:username,password_encrypted:encrypted_pwd,metadata:metadataor{},updated_at:str(__import__(datetime).datetime.now())}self._write_vault(vault)print(f已存储凭证{service_name}-{username})defget_credential(self,service_name):获取凭证——解密后返回vaultself._read_vault()ifservice_namenotinvault:raiseKeyError(f未找到凭证{service_name})entryvault[service_name]# 解密密码decrypted_pwdself.cipher.decrypt(entry[password_encrypted].encode()).decode()return{username:entry[username],password:decrypted_pwd,metadata:entry.get(metadata,{})}deflist_services(self):列出所有已存储的服务名不泄露密码vaultself._read_vault()returnlist(vault.keys())defdelete_credential(self,service_name):删除凭证vaultself._read_vault()ifservice_nameinvault:delvault[service_name]self._write_vault(vault)print(f已删除凭证{service_name})def_read_vault(self):读取凭证文件ifnotos.path.exists(self.vault_path):return{}try:withopen(self.vault_path,r)asf:returnjson.load(f)except(json.JSONDecodeError,IOError):return{}def_write_vault(self,vault):写入凭证文件withopen(self.vault_path,w)asf:json.dump(vault,f,indent2,ensure_asciiFalse)# 限制文件权限仅当前用户可读写os.chmod(self.vault_path,0o600)# 使用示例 # 初始化——主密码建议从环境变量或手动输入获取cmSecureCredentialManager(vault_pathD:/RPA_Secrets/credentials.enc,master_passwordMyS3cur3M4st3rPss)# 存储凭证cm.store_credential(service_name公司邮箱,usernamelin.yancompany.com,passwordemail_app_password_123,metadata{smtp_server:smtp.company.com,port:587})cm.store_credential(service_name数据库_WMS,usernamerpa_robot,passwordDbPssw0rd2024!,metadata{host:192.168.1.100,database:wms_prod})# 使用时获取credcm.get_credential(公司邮箱)print(f邮箱登录{cred[username]})# 注意不要在日志里打印密码# 直接传给SMTP登录函数即可第四步Python节点中使用——解密即用即弃# 影刀Python节点安全的数据库连接 importpymysql# 初始化凭证管理器主密码从影刀全局变量读取cmSecureCredentialManager(vault_pathD:/RPA_Secrets/credentials.enc,master_passwordMASTER_KEY# 影刀全局变量)# 获取数据库凭证credcm.get_credential(数据库_WMS)# 建立连接——密码存在变量中用完最好不打印connpymysql.connect(hostcred[metadata][host],usercred[username],![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d7bbf1bc2e56407395395e36a79f210c.png#pic_center)passwordcred[password],# 这里用完就完databasecred[metadata][database],charsetutf8mb4)# 执行业务逻辑cursorconn.cursor()cursor.execute(SELECT COUNT(*) FROM orders WHERE statuspending)countcursor.fetchone()[0]print(f待处理订单{count})# 清理——密码变量不要残留在内存中delcred conn.close()第五步更安全的选择——Windows凭据管理器如果你的流程只跑在Windows上可以直接调用系统的凭据管理器安全性更高由操作系统保护。 需要安装pip install keyring importkeyring# 存储凭证只需执行一次keyring.set_password(yingdao_rpa,公司邮箱,email_app_password_123)keyring.set_password(yingdao_rpa,数据库_WMS,DbPssw0rd2024!)# 使用时获取passwordkeyring.get_password(yingdao_rpa,数据库_WMS)print(f密码已从Windows凭据管理器读取长度{len(password)})# 列出所有服务名importkeyring.backends.Windowsprint(keyring.get_credential(yingdao_rpa,公司邮箱))Windows凭据管理器可以在「控制面板 → 凭据管理器 → Windows凭据」中手动查看和管理是生产环境的推荐方案。有什么坑坑1主密码丢失 → 所有凭证报废AES加密是单向的——主密码丢了所有加密的凭证就无法解密了。没有后门没有恢复机制。踩坑实录把主密码写在一个txt文件里换电脑时忘了备份三周后需要改流程发现所有凭证都解不开了只能挨个重置密码。解决方法主密码至少备份在两个独立的地方比如1Password 纸质记录。生产环境用keyring的Windows凭据管理器没有主密码的问题。坑2影刀全局变量 ≠ 加密影刀的全局变量是「不导出到分享文件」不是「加密存储」。在影刀服务端可能是明文存的。别把真正的生产密码放里面。TEMU店群如何管理运营正确姿势影刀全局变量只放主密码的引用比如密码文件路径不放密码本身。坑3日志/截图泄密即使密码没写在代码里但调试时print(password)打出密码或者截图时刚好截到了密码框一样泄露。解决方法生产流程严禁打印密码变量调试完成后删除所有print(password)语句截图前确认没有敏感信息在屏幕上坑4keyring跨平台兼容性在Windows上用keyring没问题调用Windows凭据管理器但如果你把这个流程移到Mac上跑keyring的后端就变了Mac用Keychain行为可能不一致。解决方法确定运行平台后再选方案。Windows用keyring或直接调win32credLinux可以考虑secretstorage。坑5版本控制中的凭证泄露即使你没把凭证写在代码里但如果把credentials.enc文件不小心提交到Git了虽然加密了但如果主密码很弱比如123456一样能被暴力破解。解决方法把.enc、.key、包含密码的配置文件都加入.gitignore。总结密码安全的铁律——永远不要明文写在代码里。轻量方案用AES本地加密生产环境用Windows凭据管理器。关键是形成习惯每个需要密码的地方第一反应是「从凭证管理器拿」而不是「先写死回头再改」。