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

ipfs key sign|verify #10230

Closed
lidel opened this issue Nov 22, 2023 · 3 comments · Fixed by #10235
Closed

ipfs key sign|verify #10230

lidel opened this issue Nov 22, 2023 · 3 comments · Fixed by #10235
Assignees
Labels
kind/enhancement A net-new feature or improvement to an existing feature need/analysis Needs further analysis before proceeding need/maintainers-input Needs input from the current maintainer(s) topic/security Topic security

Comments

@lidel
Copy link
Member

lidel commented Nov 22, 2023

This is a placeholder issue for implementing commands that allow the end user to sign arbitrary bytes with one of the keys (over CLI and RPC).

Constraints

  • Allow for signing of arbitrary bytes without worrying they will get mangled when sent over HTTP RPC At /api/v0/
    • We had this problem in ipfs pubsub and we ended up base-encoding the payload to avoid mangling in transit (fix: multibase in pubsub http rpc #8183)
    • Suggestion: do the same, and require binary blobs such as signature or <data> sent on the wire to be encoded in multibase64

Command design

    ipfs key sign <data>          - Generates a signature for the given data with a specified key
    ipfs key verify <data>        - Verify that the given data and signature match
    
    -k, --key       - string, key name to use for signing
    -s, --signature - string, multibase-encoded signature to verify
    -b              - string, multibase encoding of the output

To remove any ambiguity, we should use JSON output:

$ echo -n "text to sign" | ipfs key sign -k keyname
{ 
  "Key": "cidv1-libp2p-key",
  "Signature": "[multibase64url-encoded-signature]",
  "Err": "[null-or-string-error]"
}

for verify also allow passing third-party keys as cidv1 with libp2p-key codec:

$ echo -n "text to sign" | ipfs key verify -k keyname-or-cid -s signature-in-multibase
{
  "Key": "cidv1-libp2p-key",
  "SignatureValid": true|false,
  "Err": "[null-or-string-error]" // used when passed key does not exist or signature/key bytes could not be decoded
}
 

Use cases

@lidel lidel added the kind/enhancement A net-new feature or improvement to an existing feature label Nov 22, 2023
@Jorropo
Copy link
Contributor

Jorropo commented Nov 23, 2023

This is tricky, digital signatures are harder to use than it looks, for example some ethereum applications would sign arbitrary bytes and attackers could inject theses to be let's say an ethereum transaction.

Then there were the development of https://eips.ethereum.org/EIPS/eip-712 which adds enough salting that if you fuck it up this is limited to one dapp, not complete account take over.

Given here keys don't hold money this is less of concern but overall without knowing how the user is gonna use them this seems a bit reckless.
If anything, if we really need plain bytes signatures, I think it's better if users extract the private key and handle the signature themselves, this sounds dodgy, but that because signing arbitrary bytes is.

@lidel
Copy link
Member Author

lidel commented Nov 24, 2023

Before filling this issue, I did some threat modeling and RPC /api/v0/key/export does not work over HTTP, only works in offline mode where ipfs has direct access to the repo filesystem at IPFS_PATH.

  • This means it is not possible for a dapp granted limited access to RPC (Sandboxing for MFS, Keys, IPNS #10229) to export a key over HTTP Kubo RPC and do signing. Key export requires physical access to the disk.

You have a fair point about user-friendly signing methods always being prefixed:

If anything, if we really need plain bytes signatures

For real use cases like Brave and dapps/extensions with scoped RPC access (#10229), we don't:
What we need is a way to a link between IPNS key owner and some other system can be confirmed fast and offline, without publishing something and having to resolve the IPNS record first.

We could restrict ipfs key sign|verify commands to payloads prefixed with something unique like libp2p-key signed message:, making it portable between systems if required, but remove the signature-reuse problem.

Thoughts?

@lidel lidel added need/analysis Needs further analysis before proceeding need/maintainers-input Needs input from the current maintainer(s) topic/security Topic security labels Nov 24, 2023
@Jorropo
Copy link
Contributor

Jorropo commented Nov 24, 2023

The prefix is good, it gets 80% of the safety here.
Ideally you also want a scope per usecase (and not bestow the application to do that, since some people just don't).

So something like this hash("libp2p-key signed message:"+hash(brave/ipns-proof-challenge)+hash(random_salt)+hash(domain)) looks good to me at first glance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement A net-new feature or improvement to an existing feature need/analysis Needs further analysis before proceeding need/maintainers-input Needs input from the current maintainer(s) topic/security Topic security
Projects
No open projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants