pynacl
pynacl copied to clipboard
Add utility for loading a secret key from a defined format
The secret key for use with e.g. secretbox should be 32 random bytes. A common mistake is to use only bytes that can be easily typed on a keyboard, like "secret password change me [padded to 32 bytes]" or E%m"lBVK=9&m6GRkm9n'c17C6Csd9?0C.
Part of the reason people do this is that E%m"lBVK=9&m6GRkm9n'c17C6Csd?0C is easier to store in e.g. a YAML file or environment variable than b'\xbf\x9e\x0e\xe6J\xe0T,\xc6\xa5\x81i\xc9\xf2\xb1#?\xf1\xa8\x96Q\xc9\x84\xe9\x8f\xe5\xec\x921\x06\xb2\xef'.
It might be good to define a standardized format in nacl.utils for loading printable, config-safe keys, into 32 bytes of random. One would be to load 64 hex bytes, like a20fbda2e9143075aa2a919c941eaad86652b17eacc4bc816fe399ce2b78c11d, into 32 random bytes.
Then you would put SECRET_KEY=a20fbda2e9143... in the environment and write:
key = nacl.utils.load('a20fbda2e9143075aa2a919c941eaad86652b17eacc4bc816fe399ce2b78c11d')
# or
key = nacl.utils.load(os.environ['SECRET_KEY'])
or load_32 etc. I maintain a Go nacl client and this is the strategy I use for letting users load keys. https://godoc.org/github.com/kevinburke/nacl#Load
Alternatively, you could have load_from_password('hunter2'), which could derive 32 bytes of random from a string using a suitable key derivation function like scrypt.
I think this is mostly a documentation problem, and I'd reccomend against any kind of direct secret key [de-]serialization. Instead, we should point users to generate and serialize a random salt and then derive secrets via a good password-based key derivation functions like the pynacl provided argon2d scrypt, or pbkdf
I want to argue that this is a needed functionality as well: Unless you're arguing that users shouldn't have any secrets with a lifetime longer than one run of the program, there needs to be some kind of support for saving and loading them in well-defined formats.
(I'm sure this is a documentation question, but it's still and important one. Whether I'm serializing and saving a private key as such, or I'm saving an initial salt value and re-deriving the key, I still need a process for turning the results of that process into a PyNACL SigningKey (or PrivateKey) object. I'm positive it's possible, and I'm even pretty sure I've done it before, but I don't see how to do it now.) Any input would be welcome.
any progress on this issue? the lib is kinda unusable without this no?
I ended up writing a helper myself... you can still pass raw bytes directly to pynacl
Do you have a snippet somewhere ? Would appreciate a link.
There is now a draft standard for serializing Ed25519 keys in ASN.1 format: RFC 8410.