-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: move kubo-specific docs (#10226)
* docs: move kubo-specific docs * chore: note crypt cmd does not exist Context: ipfs/specs#455 --------- Co-authored-by: Marcin Rataj <lidel@lidel.org>
- Loading branch information
Showing
5 changed files
with
705 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,295 @@ | ||
# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) Keystore | ||
|
||
**Authors(s):** | ||
- [whyrusleeping](github.com/whyrusleeping) | ||
- [Hector Sanjuan](github.com/hsanjuan) | ||
|
||
**Abstract** | ||
|
||
This spec provides definitions and operations for the keystore feature in IPFS. | ||
|
||
# Table of Contents | ||
|
||
- [Goals](#goals) | ||
- [Planned Implementation](#planned-implementation) | ||
- [Key storage](#key-storage) | ||
- [Interface](#interface) | ||
- [Code changes and additions](#code-changes-and-additions) | ||
- [Structures](#structures) | ||
|
||
## Goals | ||
|
||
To have a secure, simple and user-friendly way of storing and managing keys | ||
for use by ipfs. As well as the ability to share these keys, encrypt, decrypt, | ||
sign and verify data. | ||
|
||
## Planned Implementation | ||
|
||
### Key storage | ||
|
||
Storage layout and format is defined in the [`repository_fs`](repository_fs.md) part of the spec. | ||
|
||
### Interface | ||
|
||
#### ipfs key | ||
|
||
``` | ||
USAGE | ||
ipfs key - Create and list IPNS name keypairs | ||
ipfs key | ||
'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name | ||
publish'. | ||
> ipfs key gen --type=rsa --size=2048 mykey | ||
> ipfs name publish --key=mykey QmSomeHash | ||
'ipfs key list' lists the available keys. | ||
> ipfs key list | ||
self | ||
mykey | ||
SUBCOMMANDS | ||
ipfs key export <name> - Export a keypair | ||
ipfs key gen <name> - Create a new keypair | ||
ipfs key import <name> <key> - Import a key and prints imported key id | ||
ipfs key list - List all local keypairs. | ||
ipfs key rename <name> <newName> - Rename a keypair. | ||
ipfs key rm <name>... - Remove a keypair. | ||
ipfs key rotate - Rotates the IPFS identity. | ||
For more information about each command, use: | ||
'ipfs key <subcmd> --help' | ||
``` | ||
|
||
#### ipfs crypt | ||
|
||
**NOTE:** as of 2023 Q4, `ipfs crypt` commands are not implemented yet. | ||
|
||
``` | ||
ipfs crypt - Perform cryptographic operations using ipfs keypairs | ||
SUBCOMMANDS: | ||
ipfs crypt sign <data> - Generates a signature for the given data with a specified key | ||
ipfs crypt verify <data> <sig> - Verify that the given data and signature match | ||
ipfs crypt encrypt <data> - Encrypt the given data | ||
ipfs crypt decrypt <data> - Decrypt the given data | ||
DESCRIPTION: | ||
`ipfs crypt` is a command used to perform various cryptographic operations | ||
using ipfs keypairs, including: signing, verifying, encrypting and decrypting. | ||
``` | ||
|
||
#### Some subcommands: | ||
|
||
##### ipfs key Gen | ||
|
||
|
||
``` | ||
USAGE | ||
ipfs key gen <name> - Create a new keypair | ||
SYNOPSIS | ||
ipfs key gen [--type=<type> | -t] [--size=<size> | -s] | ||
[--ipns-base=<ipns-base>] [--] <name> | ||
ARGUMENTS | ||
<name> - name of key to create | ||
OPTIONS | ||
-t, --type string - type of the key to create: rsa, ed25519. Default: | ||
ed25519. | ||
-s, --size int - size of the key to generate. | ||
--ipns-base string - Encoding used for keys: Can either be a multibase | ||
encoded CID or a base58btc encoded multihash. Takes | ||
{b58mh|base36|k|base32|b...}. Default: base36. | ||
``` | ||
|
||
* * * | ||
|
||
##### Key Send | ||
|
||
``` | ||
USAGE | ||
ipfs key - Create and list IPNS name keypairs | ||
SYNOPSIS | ||
ipfs key | ||
DESCRIPTION | ||
'ipfs key gen' generates a new keypair for usage with IPNS and 'ipfs name | ||
publish'. | ||
> ipfs key gen --type=rsa --size=2048 mykey | ||
> ipfs name publish --key=mykey QmSomeHash | ||
'ipfs key list' lists the available keys. | ||
> ipfs key list | ||
self | ||
mykey | ||
SUBCOMMANDS | ||
ipfs key export <name> - Export a keypair | ||
ipfs key gen <name> - Create a new keypair | ||
ipfs key import <name> <key> - Import a key and prints imported key id | ||
ipfs key list - List all local keypairs. | ||
ipfs key rename <name> <newName> - Rename a keypair. | ||
ipfs key rm <name>... - Remove a keypair. | ||
ipfs key rotate - Rotates the IPFS identity. | ||
For more information about each command, use: | ||
'ipfs key <subcmd> --help' | ||
``` | ||
|
||
##### Comments: | ||
|
||
Ensure that the user knows the implications of sending a key. | ||
|
||
* * * | ||
|
||
##### Crypt Encrypt | ||
|
||
``` | ||
ipfs crypt encrypt <data> - Encrypt the given data with a specified key | ||
ARGUMENTS: | ||
data - The filename of the data to be encrypted ("-" for stdin) | ||
OPTIONS: | ||
-k, -key string - The name of the key to use for encryption (default: localkey) | ||
-o, -output string - The name of the output file (default: stdout) | ||
-c, -cipher string - The cipher to use for the operation | ||
-m, -mode string - The block cipher mode to use for the operation | ||
DESCRIPTION: | ||
'ipfs crypt encrypt' is a command used to encypt data so that only holders of a certain | ||
key can read it. | ||
``` | ||
|
||
##### Comments: | ||
|
||
This should probably just operate on raw data and not on DAGs. | ||
|
||
* * * | ||
|
||
##### Other Interface Changes | ||
|
||
We will also need to make additions to support keys in other commands, these changes are as follows: | ||
|
||
- `ipfs add` | ||
- Support for a `-encrypt-key` option, for block encrypting the file being added with the key | ||
- also adds an 'encrypted' node above the root unixfs node | ||
- Support for a `-sign-key` option to attach a signature node above the root unixfs node | ||
|
||
- `ipfs block put` | ||
- Support for a `-encrypt-key` option, for encrypting the block before hashing and storing | ||
|
||
- `ipfs object put` | ||
- Support for a `-encrypt-key` option, for encrypting the object before hashing and storing | ||
|
||
- `ipfs name publish` | ||
- Support for a `-key` option to select which keyspace to publish to | ||
|
||
### Code changes and additions | ||
|
||
This sections outlines code organization around this feature. | ||
|
||
#### Keystore package | ||
|
||
The fsrepo carries a `keystore` that can be used to load/store keys. The keystore is implemented following this interface: | ||
|
||
```go | ||
// Keystore provides a key management interface | ||
type Keystore interface { | ||
// Has returns whether or not a key exist in the Keystore | ||
Has(string) (bool, error) | ||
// Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists | ||
Put(string, ci.PrivKey) error | ||
// Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey | ||
// otherwise. | ||
Get(string) (ci.PrivKey, error) | ||
// Delete removes a key from the Keystore | ||
Delete(string) error | ||
// List returns a list of key identifier | ||
List() ([]string, error) | ||
} | ||
``` | ||
|
||
Note: Never store passwords as strings, strings cannot be zeroed out after they are used. | ||
using a byte array allows you to write zeroes over the memory so that the users password | ||
does not linger in memory. | ||
|
||
#### Unixfs | ||
|
||
- new node types, 'encrypted' and 'signed', probably shouldn't be in unixfs, just understood by it | ||
- if new node types are not unixfs nodes, special consideration must be given to the interop | ||
|
||
- DagReader needs to be able to access keystore to seamlessly stream encrypted data we have keys for | ||
- also needs to be able to verify signatures | ||
|
||
#### Importer | ||
|
||
- DagBuilderHelper needs to be able to encrypt blocks | ||
- Dag Nodes should be generated like normal, then encrypted, and their parents should | ||
link to the hash of the encrypted node | ||
- DagBuilderParams should have extra parameters to accommodate creating a DBH that encrypts the blocks | ||
|
||
#### New 'Encrypt' package | ||
|
||
Should contain code for crypto operations on dags. | ||
|
||
Encryption of dags should work by first generating a symmetric key, and using | ||
that key to encrypt all the data. That key should then be encrypted with the | ||
public key chosen and stored in the Encrypted DAG structure. | ||
|
||
Note: One option is to simply add it to the key interface. | ||
|
||
### Structures | ||
Some tentative mockups (in json) of the new DAG structures for signing and encrypting | ||
|
||
Signed DAG: | ||
``` | ||
{ | ||
"Links" : [ | ||
{ | ||
"Name":"@content", | ||
"Hash":"QmTheContent", | ||
} | ||
], | ||
"Data": protobuf{ | ||
"Type":"Signed DAG", | ||
"Signature": "thesignature", | ||
"PubKeyID": "QmPubKeyHash", | ||
} | ||
} | ||
``` | ||
|
||
Encrypted DAG: | ||
``` | ||
{ | ||
"Links" : [ | ||
{ | ||
"Name":"@content", | ||
"Hash":"QmRawEncryptedDag", | ||
} | ||
], | ||
"Data": protobuf{ | ||
"Type":"Encrypted DAG", | ||
"PubKeyID": "QmPubKeyHash", | ||
"Key": "ephemeral symmetric key, encrypted with public key", | ||
} | ||
} | ||
``` |
Oops, something went wrong.