You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:50:43