SeedSigner / seedsigner

Use an air-gapped Raspberry Pi Zero to sign for Bitcoin transactions! (and do other cool stuff)
MIT License
695 stars 161 forks source link

[FEATURE] Be able to use private keys from paper wallets #89

Open david-bakin opened 3 years ago

david-bakin commented 3 years ago

Use case: You've got paper wallets from bitaddress.org which have a QR code for a private key (WIF Compressed) (also for the public address, of course). And you want to:

Goal would be to assist people in moving off of paper wallets, in a secure way. (Not having to scan/type their private key into some exchange's website or something else like that.) Or, if a person really wants to stick with their paper wallet, then facilitate that in a nice air-gapped way.

kdmukai commented 3 years ago

The current approach would be something like:

A flow using SeedSigner would be:

So really the only additional SeedSigner functionality needed would be to be able to read the paper wallet's private key QR code and internally properly handle the WIF Compressed private key type. My understanding is that this would require a kind of "second-class" key within SeedSigner that couldn't support all of the built-in key/seed features (e.g. display mnemonic, export to seed QR).

In general we are always pulled in two opposite directions: We want SeedSigner to be as simple as possible to use; if a feature that might be used by 1% of people could potentially complicate the UI for 100% of people, it's a no-go. But on the other hand we want to be as secure and privacy-focused as possible. That inherently requires more complexity. My default thinking is to stuff these more advanced best practices and checks in optional settings. Those who understand the complexities turn the feature on and will understand what they're seeing, but the default completely hides it from less advanced users so they never even see it.

tldr: I'd like to support this use case. But only if we can hide it or integrate it with zero UI confusion/impact. And probably it goes on the to-do list but isn't a burning priority right now. And that's just my opinion; the others may disagree.

david-bakin commented 3 years ago

That "flow using seedsigner" is exactly what I was suggesting.

And w.r.t. "second class key": it wouldn't need any of those things, which would be associated with storing the private key so you could do other actions on it. It would just be an ephemeral thing that would exist only as long as this signing action used it. You'd scan the WIF QR, validate the checksum, scan the PSBT, validate that, sign it, display it, forget the whole thing.

And I do agree it needn't/shouldn't be at the top level (though it could be, for a particular user's configuration, if menus were configurable by "Uncle Jim" (Joe?) as we were talking about on Telegram yesterday).

wamoyo commented 2 years ago

Any update on this? Is there a workflow for importing a private key from a paper wallet?

SeedSigner commented 2 years ago

I don't think there has been any further development into this. Wondering if private key QR code formats are standardized at all across paper wallets. Could be onerous, but perhaps an option to type the private key directly into SeedSigner might be an option, since I'd imagine most paper wallets will list the private key along with a QR representing it? Also trying to imagine what the desired use case is, because paper wallets are generally intended to be "swept" entirely, not used for ongoing transactions.

wamoyo commented 2 years ago

The thing about sweeping a private key is it's the most frightening thing on planet Earth.

"Just put your private key in here and we promise all your money will go to your wallet -wink-."

It's just so infinitely scary. You have to trust the vendor of the wallet with basically your entire life savings.

Not that there's any way around this (none that I can think of at the moment anyway).

david-bakin commented 2 years ago

Sure there is. For example, use a "mostly" airgapped laptop.

Here's what I did to move BTC from a sheaf of paper wallets to a hierarchical wallet:

  1. Ran my own bitcoin core node + Electrum server on one machine, plugged into an ethernet hub, that connected to the internet. (That was a raspiblitz I was already running.)
  2. Had a second machine that booted Linux from a USB stick (TailsOS actually) and ran Electrum client on that. NOT connected to any network at all, and the Electrum wallet was stored in encrypted storage (available built-in with TailsOS, or you could use VeraCrypt or anything like that).
  3. Disconnected the hub from the internet. Now the fully sync'd bitcoin/electrum machine was still running, connected to the hub, but disconnected from the internet.
  4. Only now connected the laptop to the hub, electrum client talking to electrum server - no internet connection.
  5. Created hierarchical wallet, backed it up, exported XPUBs, exported the list of the first receive addresses, etc.
  6. Now entered my private keys from paper wallets into the electrum client. That works because it can talk to the electrum server/bitcoin node which is still running, though disconnected from the internet. Made signed transactions to move from paper wallets to hierarchical wallet, exported those fully signed transactions to a file.
  7. Dismounted the encrypted volume holding my Electrum wallet. (Could have deleted it at that point too since I had my 24words offline.)
  8. Only now connected the hub back to the internet, let everything sync up.
  9. Created a watch only wallet in Electrum from the XPUB - no private keys there so totally safe to have that online.
  10. Now use the Electrum client on the laptop - talking to my bitcoin node/electrum server - to import the signed transactions, verify them as valid, I looked at them again to confirm they were doing the right thing, comparing addresses against my printed lists of paper wallets and hierarchical wallet receive addresses, and then I broadcast them. (You could also confirm the transactions were doing the right thing by using your own Bitcoin Core node, or any online service that lets you upload a fully signed transaction and look it it: safe, because the signed transaction doesn't have private keys, just signatures.)
  11. Watched everything show up in my watch-only Electrum wallet.

Totally safe as long as I made sure to disconnect/connect from the internet at the right times. I worked off the checklist, and it all went well.

(Plus, for extra insurance, I did the whole thing first with about $100 of BTC I bought on an exchange and exported to two paper wallets. Confirmed my checklist worked and that I knew the procedure.)

-- David

On Mon, May 2, 2022 at 4:03 PM Costa Michailidis @.***> wrote:

The thing about sweeping a private key is it's the most frightening thing on planet Earth.

"Just put your private key in here and we promise all your money will go to your wallet -wink-."

It's just so infinitely scary. You have to trust the vendor of the wallet with basically your entire life savings.

Not that there's any way around this (none that I can think of at the moment anyway).

— Reply to this email directly, view it on GitHub https://github.com/SeedSigner/seedsigner/issues/89#issuecomment-1115448817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7YLBHFCULHVTPQER73KO3VIBNKRANCNFSM5DNVWCFQ . You are receiving this because you authored the thread.Message ID: @.***>

david-bakin commented 2 years ago

P.S. there are probably simpler ways, but that's the way I did it, so you can do it that way or just use it as a proof-of-concept and search for a more optimized approach.

On Mon, May 2, 2022 at 5:27 PM David Bakin @.***> wrote:

Sure there is. For example, use a "mostly" airgapped laptop.

Here's what I did to move BTC from a sheaf of paper wallets to a hierarchical wallet:

  1. Ran my own bitcoin core node + Electrum server on one machine, plugged into an ethernet hub, that connected to the internet. (That was a raspiblitz I was already running.)
  2. Had a second machine that booted Linux from a USB stick (TailsOS actually) and ran Electrum client on that. NOT connected to any network at all, and the Electrum wallet was stored in encrypted storage (available built-in with TailsOS, or you could use VeraCrypt or anything like that).
  3. Disconnected the hub from the internet. Now the fully sync'd bitcoin/electrum machine was still running, connected to the hub, but disconnected from the internet.
  4. Only now connected the laptop to the hub, electrum client talking to electrum server - no internet connection.
  5. Created hierarchical wallet, backed it up, exported XPUBs, exported the list of the first receive addresses, etc.
  6. Now entered my private keys from paper wallets into the electrum client. That works because it can talk to the electrum server/bitcoin node which is still running, though disconnected from the internet. Made signed transactions to move from paper wallets to hierarchical wallet, exported those fully signed transactions to a file.
  7. Dismounted the encrypted volume holding my Electrum wallet. (Could have deleted it at that point too since I had my 24words offline.)
  8. Only now connected the hub back to the internet, let everything sync up.
  9. Created a watch only wallet in Electrum from the XPUB - no private keys there so totally safe to have that online.
  10. Now use the Electrum client on the laptop - talking to my bitcoin node/electrum server - to import the signed transactions, verify them as valid, I looked at them again to confirm they were doing the right thing, comparing addresses against my printed lists of paper wallets and hierarchical wallet receive addresses, and then I broadcast them. (You could also confirm the transactions were doing the right thing by using your own Bitcoin Core node, or any online service that lets you upload a fully signed transaction and look it it: safe, because the signed transaction doesn't have private keys, just signatures.)
  11. Watched everything show up in my watch-only Electrum wallet.

Totally safe as long as I made sure to disconnect/connect from the internet at the right times. I worked off the checklist, and it all went well.

(Plus, for extra insurance, I did the whole thing first with about $100 of BTC I bought on an exchange and exported to two paper wallets. Confirmed my checklist worked and that I knew the procedure.)

-- David

On Mon, May 2, 2022 at 4:03 PM Costa Michailidis @.***> wrote:

The thing about sweeping a private key is it's the most frightening thing on planet Earth.

"Just put your private key in here and we promise all your money will go to your wallet -wink-."

It's just so infinitely scary. You have to trust the vendor of the wallet with basically your entire life savings.

Not that there's any way around this (none that I can think of at the moment anyway).

— Reply to this email directly, view it on GitHub https://github.com/SeedSigner/seedsigner/issues/89#issuecomment-1115448817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7YLBHFCULHVTPQER73KO3VIBNKRANCNFSM5DNVWCFQ . You are receiving this because you authored the thread.Message ID: @.***>

wamoyo commented 2 years ago

@david-bakin Hmmm.... just thinking about a simpler way.

If I have an air gapped machine, can't I just type in my private key, and produce a raw signed transaction? The code for this must be pretty straight forward, no?

That raw transaction as a QR or hex can be scanned or typed into any node, wallet, or broadcasting service, yes?

david-bakin commented 2 years ago

I'm sure you could. For example, you could take your bitcoin core node offline and use its api to create a transaction. But I wasn't comfortable with that having no practice in it. I wanted a UI. But you said "It's just so infinitely scary. You have to trust the vendor of the wallet with basically your entire life savings. Not that there's any way around this (none that I can think of at the moment anyway)." I provided one way that had security sufficient for me. And now you're thinking about another. So ... it isn't infinitely scary ... you just have to put some thought into it (unless there's a cookbook out there someone has already thought through - if you find one let us know!)

On Tue, May 3, 2022 at 10:35 AM Costa Michailidis @.***> wrote:

@david-bakin https://github.com/david-bakin Hmmm.... just thinking about a simpler way.

If I have an air gapped machine, can't I just type in my private key, and produce a raw signed transaction? The code for this must be pretty straight forward, no?

That raw transaction as a QR or hex can be scanned or typed into any node, wallet, or broadcasting service, yes?

— Reply to this email directly, view it on GitHub https://github.com/SeedSigner/seedsigner/issues/89#issuecomment-1116366567, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA7YLBBZV4FBQSH4ZPLDON3VIFPW3ANCNFSM5DNVWCFQ . You are receiving this because you were mentioned.Message ID: @.***>

kdmukai commented 2 years ago

@wamoyo you need the utxo info in order to construct the transaction. So your airgapped machine would need a copy of the blockchain at least up to the point when the paper wallet received its last deposit.

kdmukai commented 2 years ago

@david-bakin - It would have to be a "second-class key" in order to be incorporated into our existing PSBT signing flow. It would probably be a class derived from Seed that has various options disabled.

So we probably could make the UI simple enough and keep the key ephemeral, but there'd be some code bloat to create a parallel Seed model just for this one uncommon use case.

And since my initial reply at the top, we now have a "Flow" concept under the hood that keeps track of what kind of activity you're in the middle of (e.g. you want to verify a multisig address but first you have to divert into the Load Multisig Descriptor flow so it needs to know that it should return you to the verify addr flow). So we could have a specialized "Tools" option to "Sweep Paper Wallet" and set that as the current "Flow" so that all the other components we need to reuse (scan pk, PSBT signing flow) are aware that this isn't a normal operation. And then at the conclusion of signing the PSBT, wipe the "second-class key" from memory so the user can't interact with that stripped-down Seed in any other way.

So... tentative ACK from me.

But still not a burning high priority.