How to use Python to save nacl SigningKey public and private keys as plain text?

1.1k views Asked by At

I must be missing something in the nacl docs. How do I save both the private and public keys in plain text? The available encoders are Raw (binary?), Hex, Base16/32/64 and URLSafeBase64Encoder.

I thought I would just use the base64 library to convert the Base64-encoded key.

Example:

from nacl.signing import SigningKey
from nacl.encoding import Base64Encoder
from base64 import b64decode


# Create SigningKey as base64-encoded bytes

signing_key = SigningKey.generate().encode(encoder=Base64Encoder)
print(type(signing_key))


# Convert base64-encoded bytes to string

signing_key = signing_key.decode('utf-8')
print(type(signing_key))


# Decode base64 string to plain text

signing_key = b64decode(signing_key)
print(type(signing_key))
print(signing_key)

Results: Bytes object

<class 'bytes'>
<class 'str'>
<class 'bytes'>
b'e\xfa ?H\xd8\xe7^2\xfa1\x18\xa61\xca\x95\xec~\x8c\x011[\xf8\x05q!\xfc\xe4\x94\x13\xc2\x89'

Tried:

  • The Decoding Strings with Python tutorial here, and all sorts of variations.
  • None of them lead to the plain text version of the SigningKey
  • I'm looking for the -----BEGIN OPENSSH PRIVATE KEY----- etc. in plain text
  • How do I force the b64decode function to show plain text?
1

There are 1 answers

1
Jack On BEST ANSWER

This is mostly the same as the link you attached in your comment, but here is a more succinct example that may help

signing_key = SigningKey.generate()

priv_key_b64 = signing_key.encode(encoder=Base64Encoder)
pub_key_b64  = signing_key.verify_key.encode(encoder=Base64Encoder)

data = b'testtest'

signed_b64 = signing_key.sign(data, encoder=Base64Encoder)

print(priv_key_b64)         # private key in alpha-numeric encoding
print(pub_key_b64)          # public key in alpha-numeric encoding
print(signed_b64)           # data & signature over data in single chunk

verified = signing_key.verify_key.verify(signed_b64, encoder=Base64Encoder)

print(verified)             # origin 'data' (testtest)

To respond to your comment about the seed, the SigningKey.generate() generates a random seed for you and uses that to construct a private (signing) key. You could provide your own seed using signing_key = SigningKey(seed, encoder=RawEncoder)