crypt.keysafe #
Keysafe
A safe implementation to help you sign, encrypt, decrypt and store your keys locally.
Internals
When loading a keysafe object, you can specify a directory
and a secret
. In that directory, a file called .keys
will be created and encrypted using the secret
provided (AES-CBC
).
Content of that file is a JSON dictionnary of key-name and it's mnemonic, a single mnemonic is enough to derivate ed25519
and x25519
keys.
When loaded, private/public signing key and public/private encryption keys are loaded and ready to be used.
key_generate_add()
generate a new key and store is as specified namekey_import_add()
import an existing key based on it's seed and specified name
Example
module main
import freeflowuniverse.crystallib.crypt.keysafe
fn main() {
mut ks := keysafe.keysafe_get('/tmp/', 'helloworld')!
println(ks)
ks.key_generate_add('demo') or { println(err) }
println(ks)
if ks.exists('demo') {
println('key demo exists')
}
}
Keys
Note about keys: when generating a new key, the "master key" is a SigningKey Ed25519 key. From that key, we can derivate a PrivateKey (encrypting key) X25519.
We can convert public-key only as well. On public key exchange, please always exchange the public SigningKey (aka the master key for us). Based on that SignigKey, we can derivate the Encyption PublicKey and KeysSafe does it for you.
fn key_encode #
fn key_encode(key []u8) string
fn keysafe_get #
fn keysafe_get(path0 string, secret string) !KeysSafe
Note: root key needs to be 'SigningKey' from libsodiumfrom that SigningKey we can derivate PrivateKey needed to encrypt
fn pubkey_new #
fn pubkey_new(name string, myself PrivKey, remote string) !PubKey
fn verifykey_new #
fn verifykey_new(name string, remote string) !VerifyKey
remote is the public master key which needs to verify
struct KeysSafe #
struct KeysSafe {
pub mut:
path pathlib.Path // file path of keys
loaded bool // flag to know if keysafe is loaded or loading
secret string // secret to encrypt local file
keys map[string]PrivKey // list of keys
}
fn (KeysSafe) generate_multiple #
fn (mut ks KeysSafe) generate_multiple(count int) !
for testing purposes you can generate multiple keys
fn (KeysSafe) key_generate_add #
fn (mut ks KeysSafe) key_generate_add(name string) !PrivKey
generate a new key is just importing a key with a random seed
fn (KeysSafe) key_import_add #
fn (mut ks KeysSafe) key_import_add(name string, seed []u8) !PrivKey
import based on an existing seed
fn (KeysSafe) get #
fn (mut ks KeysSafe) get(name string) !PrivKey
fn (KeysSafe) exists #
fn (mut ks KeysSafe) exists(name string) bool
fn (KeysSafe) key_add #
fn (mut ks KeysSafe) key_add(pk PrivKey) !
fn (KeysSafe) persist #
fn (mut ks KeysSafe) persist()
fn (KeysSafe) serialize #
fn (mut ks KeysSafe) serialize() string
fn (KeysSafe) load #
fn (mut ks KeysSafe) load()
fn (KeysSafe) deserialize #
fn (mut ks KeysSafe) deserialize(input string)
struct PersistantKeysSafe #
struct PersistantKeysSafe {
pub mut:
keys map[string]string // store name/mnemonics only
}
struct PrivKey #
struct PrivKey {
pub:
name string
mnemonic string
signkey libsodium.SigningKey // master key
privkey libsodium.PrivateKey // derivated from master key
}
fn (PrivKey) master_public #
fn (key PrivKey) master_public() string
retrieve the master public key from PrivKey object this is the public key as need to be shared to a remote user to verify that we signed with our private key is shared as hex key in string format (66 chars)
fn (PrivKey) sign #
fn (key PrivKey) sign(data []u8) []u8
sign data with our signing key data is bytestr output is []u8 bytestring to get bytes from string do: mystring.bytes().
fn (PrivKey) sign_hex #
fn (key PrivKey) sign_hex(data []u8) string
sign data with our signing key. data is bytestr. output is hex string. to get bytes from string do: mystring.bytes(). size of output is ?
struct PubKey #
struct PubKey {
pub:
name string
source PrivKey // ourself (private key, to sign message)
remote []u8 // target public key (to encrypt)
}
fn (PubKey) encrypt #
fn (key PubKey) encrypt(data []u8) ![]u8
this will encrypt bytes so that only the owner of this pubkey can decrypt it
fn (PubKey) decrypt #
fn (key PubKey) decrypt(data []u8) []u8
verify a signed data
struct VerifyKey #
struct VerifyKey {
pub:
name string
remote libsodium.VerifyKey // target public master key
}
fn (VerifyKey) verify #
fn (key VerifyKey) verify(data []u8) bool
verify a signed data, returns true if signature is correct