无法在RethinkDB中存储字节数据的问题解决方案咨询
解决RethinkDB存储字节字符串后解密崩溃的问题
嘿,这个问题我太熟悉了!你现在碰到的核心问题是:加密后的字节对象被转成了字符串形式的字节表示(比如"b'bytesandstuff'")存在了RethinkDB里,而解密函数需要的是真实的bytes类型,自然会崩溃。
最简单的快速修复方案
不用改存储逻辑的话,最快的方法是把取回的字符串安全地转回bytes对象,这里推荐用ast.literal_eval()(比直接用eval()安全得多,它只会解析合法的Python字面量)。修改你的passgen.py代码如下:
import ast from cryptography.fernet import Fernet key = "mySecretKey" # 注意:生产环境绝对不要硬编码密钥! f = Fernet(key) def decryptPass(rawstring): # 将字符串形式的字节对象转回真实bytes byte_data = ast.literal_eval(rawstring) decrypted = f.decrypt(byte_data) converted = decrypted.decode('utf8') return converted
这样修改后,当你从RethinkDB取回"b'xxx'"格式的字符串时,ast.literal_eval()会把它解析成原始的bytes对象,解密函数就能正常工作了。
更规范的长期解决方案
虽然上面的方法能快速解决问题,但存储字节的字符串表示并不是最优实践。更规范的做法是在加密后直接把字节转成Base64字符串存储(Fernet加密后的结果本身就是Base64编码的),这样存储的是普通字符串,后续处理更省心:
修改加密函数:
def encryptPass(password): encrypted_bytes = f.encrypt(password.encode('utf8')) # 将字节转成Base64字符串存储 return encrypted_bytes.decode('utf8')
修改解密函数:
def decryptPass(rawstring): # 直接把字符串转回字节 encrypted_bytes = rawstring.encode('utf8') decrypted = f.decrypt(encrypted_bytes) return decrypted.decode('utf8')
这种方式避免了字节字符串化带来的类型混淆,也更符合数据库存储字符串的常规做法。
重要提醒
千万不要在生产环境硬编码密钥!建议用环境变量、密钥管理服务(比如AWS KMS、HashiCorp Vault)来存储和获取密钥,避免密钥泄露风险。
内容的提问来源于stack exchange,提问作者KillerDogeAlt
相关产品推荐
相关产品推荐

