Python 3 UnboundLocalError及RSA密钥文件存在性检查逻辑问题
解决你RSA加解密程序的两个坑:UnboundLocalError与密钥文件存在性检查
一、先搞定UnboundLocalError这个报错
这个错误其实很好理解——你在函数里引用了一个变量,但这个变量不是在所有代码分支里都被赋值了。比如你的genKeys()函数,如果是在某个if判断或者异常分支里才定义pubkey/privkey,那一旦走到没赋值的分支,后面再用这俩变量就会触发这个错误。
给你改个靠谱的genKeys()版本:
import rsa keySize = 256 def genKeys(): # 先给变量初始化默认值,确保所有分支都能拿到有效引用 pubkey = None privkey = None try: # 生成密钥对的核心逻辑 pubkey, privkey = rsa.newkeys(keySize) except Exception as e: print(f"生成密钥时翻车了: {e}") # 不管有没有异常,这俩变量都有值,不会触发未绑定的错误 return pubkey, privkey
要是你原来的代码是在某个条件里才给这俩变量赋值,记得要么在函数开头初始化,要么保证每个分支都给它们赋值。
二、密钥存储文件的存在性检查怎么搞?
用Python内置的os.path模块就能轻松搞定,分三步走:
1. 先定好密钥文件的路径
比如咱把公钥存public_key.pem,私钥存private_key.pem:
import os # 把路径定义成常量,后续修改起来更方便 PUBLIC_KEY_PATH = "public_key.pem" PRIVATE_KEY_PATH = "private_key.pem"
2. 写个检查文件是否存在的小函数
def check_key_files_exist(): # 必须两个文件都存在才返回True pub_exists = os.path.exists(PUBLIC_KEY_PATH) priv_exists = os.path.exists(PRIVATE_KEY_PATH) return pub_exists and priv_exists
3. 结合密钥生成和加载的完整逻辑
程序启动时先检查文件:有就加载,没有就生成并保存:
def load_keys(): if not check_key_files_exist(): print("没找到密钥文件,开始生成新的密钥对...") pubkey, privkey = genKeys() # 生成成功才保存,避免存空文件 if pubkey and privkey: with open(PUBLIC_KEY_PATH, "wb") as f: f.write(pubkey.save_pkcs1()) with open(PRIVATE_KEY_PATH, "wb") as f: f.write(privkey.save_pkcs1()) print("密钥已经存到本地文件啦") else: raise RuntimeError("密钥生成失败,没法继续了") else: print("加载本地密钥文件中...") # 从文件里读取并加载密钥 with open(PUBLIC_KEY_PATH, "rb") as f: pubkey = rsa.PublicKey.load_pkcs1(f.read()) with open(PRIVATE_KEY_PATH, "rb") as f: privkey = rsa.PrivateKey.load_pkcs1(f.read()) print("密钥加载完成") return pubkey, privkey
三、整合起来的完整代码示例
把上面的代码拼起来,就是一个能正常工作的基础版本,还加了加密解密的测试逻辑:
import rsa import os # 配置参数 keySize = 256 PUBLIC_KEY_PATH = "public_key.pem" PRIVATE_KEY_PATH = "private_key.pem" def genKeys(): pubkey = None privkey = None try: pubkey, privkey = rsa.newkeys(keySize) except Exception as e: print(f"生成密钥对出错: {str(e)}") return pubkey, privkey def check_key_files_exist(): return os.path.exists(PUBLIC_KEY_PATH) and os.path.exists(PRIVATE_KEY_PATH) def load_keys(): if not check_key_files_exist(): print("未检测到密钥文件,生成新密钥对...") pubkey, privkey = genKeys() if pubkey and privkey: with open(PUBLIC_KEY_PATH, "wb") as f: f.write(pubkey.save_pkcs1()) with open(PRIVATE_KEY_PATH, "wb") as f: f.write(privkey.save_pkcs1()) print("密钥对已保存到本地") else: raise RuntimeError("密钥生成失败,程序终止") else: print("加载本地密钥文件...") with open(PUBLIC_KEY_PATH, "rb") as f: pubkey = rsa.PublicKey.load_pkcs1(f.read()) with open(PRIVATE_KEY_PATH, "rb") as f: privkey = rsa.PrivateKey.load_pkcs1(f.read()) print("密钥加载完成") return pubkey, privkey # 测试一下功能是否正常 if __name__ == "__main__": pub, priv = load_keys() test_msg = b"这是一条测试加密消息!" encrypted_msg = rsa.encrypt(test_msg, pub) decrypted_msg = rsa.decrypt(encrypted_msg, priv) print(f"原始消息: {test_msg.decode('utf-8')}") print(f"解密后消息: {decrypted_msg.decode('utf-8')}")
几个额外的小提醒
- 私钥文件要管好:生产环境里,私钥文件的权限要设得严格点(比如Linux下
chmod 600),别让其他人随便读取 - 异常处理可以再细化:比如加个文件读写失败的捕获逻辑,避免程序直接崩溃
- 后续扩展多密钥对:可以给不同用户的密钥加前缀或者存到不同文件夹,比如
alice_public.pem、bob_private.pem这样区分
内容的提问来源于stack exchange,提问作者GarrukApex
相关产品推荐
相关产品推荐

