Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import and export ipfs private keys #4240

Closed
trenta3 opened this issue Sep 17, 2017 · 25 comments · Fixed by #7546
Closed

import and export ipfs private keys #4240

trenta3 opened this issue Sep 17, 2017 · 25 comments · Fixed by #7546
Labels
help wanted Seeking public contribution on this issue

Comments

@trenta3
Copy link

trenta3 commented Sep 17, 2017

Version information: 0.4.11-rc1-2eb4c861

go-ipfs version: 0.4.11-rc1-2eb4c861
Repo version: 6
System version: amd64/linux
Golang version: go1.8.3

Type: Feature/Bug

Severity: Low

Description: Add functionality to import and export ipfs keys

Please add commands to ipfs in order to be able to export and import (private) keys (à la gpg).

If there is no other suggestion something like ipfs key export <name> and ipfs key import <file> --name=<name> would do. They could possibly be adapted to import/export only the public key.

Reasonable usecase

I use ipns to publish my personal blog, and I'd like to be able to publish to it from more than one machine. Moreover, if my pc break I wouldn't be able to update my blog any more.

Attempt at finding a solution

Searching online I was not able to find a way to export my keys (and ipfs help shows nothing) except https://github.com/tswindell/ipfs_keys_export that apparently does not work since ipfs config Identity.PrivKey gives error Error: cannot show or change private key through API.

Quick solutions?

Apart from implementing these (which I guess may take some time), is there any hack I can now perform to be able to import/export keys? For example, are they saved in a specific file with a specific well behaving format?

@whyrusleeping
Copy link
Member

@trenta3 if making publishing keys via ipfs key gen, you can find the files for all your keys in $IPFS_PATH/keystore. The default key is still (unfortuantely) in the config file, we are planning on migrating that out soon so that it becomes available in the same place.

@pruflyos
Copy link

pruflyos commented Oct 24, 2017

What is the format of the files that are stored in $IPFS_PATH/keystore? Can those files be read with external tools like gpg?

I also wish it would be possible to really import keys (e.g. a ed25519 private key in hex format) that were created using other software and not only be able to copy a key that was created using ipfs key gen.

@matthiasbeyer
Copy link

I would like to back the request. The described use-case is perfectly reasonable IMO.

This should even be possible via the API. Usecase: One implements an App with IPFS as backend storage. End-users should be able to use the app from multiple devices (maybe even mobile). It would be necessary that they are able to sign their content with the same key from all devices.

@Kubuxu
Copy link
Member

Kubuxu commented Nov 7, 2017

Key issue here is that we don't want to expose private keys on the API, we already fixed it for key that is contained in the config file as any break in browser request sandboxing means that your keys are exposed to arbitrary websites.

@whyrusleeping
Copy link
Member

We could add a command for exporting keys that runs entirely offline (never over the api)

@pmorch
Copy link

pmorch commented Nov 19, 2017

I can totally understand that one wouldn't want the ability to extract existing keys over the API.

But it should be possible to create a key with the API and have that newly created key returned (as a result of the creation - that one time just when it got created) in a format that can be imported on another machine later.

Consider the usecase of implementing an App with IPFS as backend storage. With create-and-return keys apps can use the API to create keys for themselves to keep track of dynamic content. And the key could e.g. be kept by a browser extension synced with other browsers allowing the user to modify dynamic content.

@whyrusleeping
Copy link
Member

whyrusleeping commented Nov 19, 2017 via email

@AndreaCensi
Copy link

It seems that @pruflyos's question was not answered: what is the format for the files in ~/.ipfs/keystore?
What is the most convenient way to access them? is it possible with openssl, gpg?

@Stebalien
Copy link
Member

@AndreaCensi
Copy link

@Stebalien Thanks for the pointer - unfortunately I don't know go so the barrier to entry is a bit too high for me.

Is there an example / basic recipe to do sign/verify operations with the keys in the keystore?

Context: I am building a distributed app (in Python) on top of IPFS, and it makes a lot of sense to use the IPFS identities for the nodes. All I need is a way to 1) generate a signature; 2) verify a signature.

I have seen command-line versions proposed in the past (ipfs key sign, ipfs key verify), but I cannot find any concrete implementation.

@EB113
Copy link

EB113 commented Mar 16, 2018

If you're only interested in the IPFS APIhttps://github.com/ipfs/specs/tree/master/keystore, Author[s]: @whyrusleeping.

From a quick look into it, also never used Go-Lang, so maybe some errors:

I can see they use RSA, EC(curve=Ed25519),EC(curve=Secp256k1), check var:KeyTypes, source:key.go file.

Doing a verify or sign search in the repository, you can find test code function:testKeySignature, source:key_test.go.

The above uses mainly key.go.

File: key.go in-topic related Interfaces:
PrivKey(includes the above Key type, has a Sign and GetPublic methods)
Pubkey(includes the above Key type, has a Verify methods)

Under go-libp2p-crypto/pb/ you can see KeyType DataType, with the PublicKey and PrivateKey structs.

Each type of cipher has a file with corresponding name with encryption, decryption, signing and veryfying methods if you have curiosity.

The raw implementation of the signatures and verifications used above:
-Ed25519:https://github.com/agl/ed25519/
-Secp256k1:https://github.com/btcsuite/btcd/tree/master/btcec;
-RSA:https://golang.org/pkg/crypto/, Go-Lang package;

I also saw they had a JavaScript version but didn't look into it:
https://github.com/libp2p/js-libp2p-crypto

@Stebalien
Copy link
Member

@AndreaCensi

Is there an example / basic recipe to do sign/verify operations with the keys in the keystore?

Sorry, I missed your response. We actually use protobufs to store them (the protobufs are in the pb folder in that directory). Most commonly used languages have protobuf libraries.

When actually serializing the keys into the Data field of the protobuf, we do so as follows:

  • Ed25519: We concatenate the private key with the public key. Unfortunately, I don't know the actual format of the underlying keys as @pedroliveira95 said, we use https://github.com/agl/ed25519/).
  • RSA: We use a DER-encoded PKIX format (standard key format).
  • Secp256k1: we use RFC 5915 (I think?).

@angleman
Copy link

I'm not sure this will help but I'm seeing the following with go-ipfs@0.4.16 (repo version 7) in the ~/.ipfs/config file:

{
  "Identity": {
    "PeerID": "Qmbjna...",
    "PrivKey": "RHwz3..."
  },
  "Datastore": { ... 

It appears that "PrivKey" may be what you are looking for.

@pruflyos
Copy link

@angleman ~/.ipfs/config only contains the identity key of the local IPFS node.
However, this issue is about importing the keys for IPNS names. See ipfs key --help for details.
I would update the title of this issue to be more specific if I could.

@lidel
Copy link
Member

lidel commented May 22, 2019

@Stebalien thoughts on adding import / export to go-ipfs?
Would it be enough to exclude self and limit export to keys created via API (as suggested in #4240 (comment))? Maybe we could add an opt-in flag to key gen that marks newly created key key as "safe to export".

@satazor mentioned they will need them for IDM Wallet UI (ipfs-shipyard/nomios-web).

I checked and we have a discrepancy between go-ipfs and js-ipfs right now.
Both js-ipfs and interface-js-ipfs-core list key import and key export commands:

@Stebalien
Copy link
Member

So, we should totally allow import. As for export, I'm fine with export as a local command but I'm concerned about supporting it via the API.

@satazor mentioned they will need them for IDM Wallet UI (ipfs-shipyard/nomios-web).

Do they really need export?

@satazor
Copy link

satazor commented Jul 30, 2019

@Stebalien We don't need the export. We are using:

  • .dag.get
  • .dag.put
  • .name.resolve
  • .name.publish
  • .key.list
  • .key.import
  • .key.rm

You may check the code here: https://github.com/ipfs-shipyard/js-did-ipid/blob/master/src/index.js

Hope that helps!

@Stebalien Stebalien added the help wanted Seeking public contribution on this issue label Nov 16, 2019
@bonedaddy
Copy link
Contributor

Use mnemonic phrases, it's become pretty standard for handling PK's with blockchains and is easily transportable. The only issue is RSA keys which due to their bit sizes produce massive mnemonic phrases. Could always just hex encode and then feed that into a mnemonic phrase generator to reduce size

I've been using a mnemonic phrase exporter for ipfs keys in prod for ~1yr and its been working quite well. See here for an example.

@rendaw
Copy link

rendaw commented Jul 15, 2020

I think this is really important. I've been hesitant to try out ipfs because if I actually started using it for publishing, losing my private key would mean starting over from scratch. A backup story other than "copy your whole ipfs store" is necessary I think.

What about just backing up keystore or specific files from there? Whether that directory structure is guaranteed or not, I think there's another issue here that if you need to restore and the newest version has a different model version + needs a migration you'll have to create a dummy .ipfs store of the old version to put your key in to do the migration...

Do they really need export?

Export is needed for people who have generated their keys before this feature was implemented and want to back them up I think.

@Stebalien
Copy link
Member

Stebalien commented Jul 15, 2020 via email

@rendaw
Copy link

rendaw commented Jul 16, 2020

What would be the restore procedure for that? init won't work if you only have those files and the data format may have changed since, right?

@Stebalien
Copy link
Member

Stebalien commented Jul 16, 2020 via email

@rendaw
Copy link

rendaw commented Jul 16, 2020

Great, just wanted to make sure my understanding was correct here. I opened ipfs/interface-go-ipfs-core#64 since I think that's the first change that will need to happen, although if you have pointers about the order of projects in which changes need to be made that would be helpful.

@Stebalien
Copy link
Member

Stebalien commented Jul 16, 2020 via email

@rendaw
Copy link

rendaw commented Jul 16, 2020

Perfect, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Seeking public contribution on this issue
Projects
No open projects
Development

Successfully merging a pull request may close this issue.