在python PyNaCl中从数据库中检索加密密钥,如何将其转换回PublicKey或PrivateKey对象?

时间:2018-03-29 11:28:01

标签: python typeerror libsodium

我正在尝试将私钥/公钥存储为数据库中的UTF-8字符串。问题是,当我将它们带回代码时,它们不是正确的类型。作为字节,它们打印相同,如下面的代码所示:

import nacl.utils
from nacl.public import PrivateKey, SealedBox
from nacl.encoding import Base64Encoder
import base64


prvkbob = PrivateKey.generate()
pubkbob = prvkbob.public_key

prvk_db = prvkbob.encode(Base64Encoder).decode('utf8')
pubk_db = pubkbob.encode(Base64Encoder).decode('utf8')

prvk = base64.b64decode(prvk_db.encode('utf8'))
shdk = base64.b64decode(pubk_db.encode('utf8'))

print(prvkbob)
print(prvk)

print(pubkbob)
print(shdk)

# It works with the original key
sealed_box = SealedBox(prvkbob)

# Error on key returned from database
sealed_box = SealedBox(prvk)

如何将它们初始化为PublicKey或PrivateKey对象?

2 个答案:

答案 0 :(得分:1)

我参加聚会可能有点晚了,但是我遇到了一个类似的问题,它说:

  

nacl.exceptions.TypeError:必须根据私钥和   公钥

通过使用以下几行实例化公钥或私钥实例,可以轻松解决此问题:

imported_private_key = nacl.public.PrivateKey(bytes_that_are_a_key)
imported_public_key = nacl.public.PublicKey(bytes_that_are_a_key)

我希望它可以帮助您或其他遇到相同问题的人

答案 1 :(得分:1)

由于您已在 utf-8 .decode('utf8'))中对密钥进行了显式解码,因此必须首先使用完全相同的编码对它们进行编码(就像您所做的那样)。就像@DisplayName所说的那样,您只需要实例化PrivateKeyPublicKey

由于您计划存储这些键的 Base64 表示形式,因此可以执行以下操作。以下是按您希望的方式生成的键:

john_private = "OSEuOrw7BDANm2b0lwddBXUxN6OFGBLBDoFbqnkdMNU="
john_public  = "bQNbTjHETLTc/RNJYa1mTDg0fQF70GsuIZFsrb43DQc="

paul_private = "ry860ekZ8T1UDTzvoPSlAVMEOjcVz3ODLYbjXfySns0="
paul_public  = "G8608AL7TE2n3P10OLS8V/8wCaf/mzflCS/5qw/TzG4="

这两个功能与存储在Base64中的消息一起使用

def base64_to_bytes(key:str) -> bytes: 
    return base64.b64decode(key.encode('utf-8'))

def encrypt_for_user(sender_private:str, receiver_public:str, message:str) -> str: 
    sender_private = PrivateKey(base64_to_bytes(sender_private))
    receiver_public = PublicKey(base64_to_bytes(receiver_public))
    sender_box = Box(sender_private, receiver_public)

    return base64.b64encode(sender_box.encrypt(bytes(message, "utf-8"))).decode('utf-8')

def decrypt_for_user(receiver_private:str, sender_public:str, message:str) -> str: 
    receiver_private = PrivateKey(base64_to_bytes(receiver_private))
    sender_public = PublicKey(base64_to_bytes(sender_public))
    receiver_box = Box(receiver_private, sender_public)

    return receiver_box.decrypt(base64.b64decode(message.encode('utf-8'))).decode('utf-8')

John向Paul发送了一条消息:

message = encrypt_for_user(john_private,paul_public,"Hi Paul, 'up?")
print(message)
9BxTezSQVlxPU5evODskj4EIb5hXqIPnkQVuhpY2qoYvcnIaBgUVhkbN8baSytsmF4RSXdI=

Paul解密:

decrypt_for_user(paul_private, john_public, message)
"Hi Paul, 'up?"