Python PyNaCl中从数据库取回加密密钥后如何转为PublicKey/PrivateKey对象?
解决nacl密钥存储数据库后无法还原为正确类型的问题
我之前也碰到过类似的坑!你现在的问题核心是还原密钥时的解码流程搞反了,虽然字节打印看起来一致,但实际上你传给密钥构造函数的是Base64编码后的字节,不是原始的密钥字节。
先看你原来的代码逻辑(我补全了取回还原的部分):
import nacl.utils from nacl.public import PrivateKey, SealedBox, PublicKey from nacl.encoding import Base64Encoder import base64 # 生成密钥 prvkbob = PrivateKey.generate() pubkbob = prvkbob.public_key # 存储到数据库:Base64编码→转UTF-8字符串 prvk_db = prvkbob.encode(Base64Encoder).decode('utf8') pubk_db = pubkbob.encode(Base64Encoder).decode('utf8') # 错误的还原方式:直接把UTF-8字符串转字节传给构造函数 # prvk_restore = PrivateKey(prvk_db.encode('utf8')) # 这里会报错 # pubk_restore = PublicKey(pubk_db.encode('utf8')) # 这里也会报错
问题原因
PrivateKey和PublicKey的构造函数默认接收的是原始的32字节私钥/公钥数据,但你现在传的是Base64编码后的字节(比如私钥Base64编码后是44字节左右),类型不匹配自然无法正确解析。
正确的还原方法
有两种简洁的方式可以解决:
方式1:手动逆流程解码
先把数据库取回的UTF-8字符串转成字节,再用Base64解码得到原始密钥字节,再传给构造函数:
# 从数据库取回字符串后 prvk_bytes = base64.b64decode(prvk_db) prvk_restore = PrivateKey(prvk_bytes) pubk_bytes = base64.b64decode(pubk_db) pubk_restore = PublicKey(pubk_bytes)
方式2:利用nacl自带的编码器(推荐)
nacl的密钥构造函数支持直接传入编码后的字符串,只要指定对应的编码器,它会自动完成解码:
# 从数据库取回字符串后直接还原 prvk_restore = PrivateKey(prvk_db, encoder=Base64Encoder) pubk_restore = PublicKey(pubk_db, encoder=Base64Encoder)
验证方法
你可以对比还原前后的Base64字符串,确认是否一致:
print(prvk_restore.encode(Base64Encoder).decode('utf8') == prvk_db) # 应该输出True print(pubk_restore.encode(Base64Encoder).decode('utf8') == pubk_db) # 应该输出True
这样还原后的密钥就能正常用于SealedBox等加密操作了。
内容的提问来源于stack exchange,提问作者zamarov
相关产品推荐
相关产品推荐

