Feature Request: Startup Passphrase
A feature that I have often seen requested, and one which I agree would be a nice addition, is to allow the wallet to be configured to require a passphrase at startup in order to open it. Currently, the wallet requires a passphrase to actually spend funds, but it is quite bad for privacy in situations where there is a shared computer usage. Another scenario is where one might need to have their computer repaired. I doubt anyone who is privacy conscious would want the technician to be able to open up their wallet and see all of their details, even though they can't actually steal the funds.
Often the request has been made to allow it to be different than the passphrase required to spend funds, although I personally feel like it should be the same one. My reasoning for that is not only does it provide a simpler user experience (simplicity is nearly always appreciated by the largest number of users), it is also less complex to implement since the code already exists to safely store and verify the spending passphrase in the underlying dcrwallet database.
I agree it would be a nice addition.
We currently support opening wallets protected with a public passphrase (passphrase is requested during wallet startup), but we don't have a way of specifying it during wallet creation, so we need to add that.
However, going by this comment on dcrwallet and looking at how the underlying udb.Open is actually implemented (pubPass is passed to the address manager but not to tx store), it seems to me the tx history data of the wallet is currently not encrypted (would love to be proven wrong though - if the comment is wrong and tx data actually is encrypted, let's fix that).
So adding the public passphrase doesn't actually prevent anyone with access to the wallet.db from finding your current full history - the repairman scenario and the multiuser scenario if the wallet files aren't protected by appropriate file permissions.
Again, if I missed the place where the pubPass is in fact being used to encrypt stuff in the tx store, let me know and we can start the work for specifying it during wallet creation time, but otherwise just adding the password without the underlying data being protected doesn't seem right to me.
This is correct. We previously removed the ability to set the public passphrase during wallet creation in Paymetheus because it provides misleading security (in addition to the worse UX of having two passphrases).
I lean in the direction that this feature belongs at the filesystem level instead of the application level. If a second encrypted filesystem is mounted which contains the wallet, the extra encryption is handled transparently by the OS. This does complicate the setup for users, but it's a more foolproof solution than trying to implement it directly into dcrwallet.
For those of us who are tech savvy, an encrypted filesystem is indeed the best approach, but it's also just not very realistic for users to do. I really don't think it's a good idea to just punt here, because all arguments about implementation details aside, being able to open the wallet without a passphrase for most users, particularly Windows users, really is not a nice user experience from a privacy perspective, and asking them to go through, what for most Windows users, is a complicated process, just really is not a reasonable ask.
I would suggest looking at something like Exodus, which is completely catered towards the user experience. Even wallets like that, which are entirely focused on UX over everything else, provide the option to require the passphrase at startup.
I agree we should support it, it should be user friendly, if we could get away with using filesystem level encryption it would be better (but we can't) and therefore will be a hard work to correctly implement.
Re: two passwords, one of the replies in the reddit thread that prompted this issue was actually advocating that approach, so there is a class of users which would use this feature.
What would be the correct way of implementing this on the wallet? A new walletdb driver that fully encrypts everything? Modifying the txstore to actually encrypt/decrypt stuff (but then there's all the stuff about indexes, number of records implying number of transactions, etc)?
It's not possible without rewriting how various wallet data is stored and retrieved. The txstore code makes extensive use of cursors (and prefix cursors) that contain transaction hashes, and the cursors would not iterate in the correct order if the keys were encrypted.
Can anyone clarify if using the private passphrase in this instance would be a problem (to keep only one password)? On the UX side, option to simplify it for the users could using a 4-6 digit numerals pin format as a launch password. Instead of two passwords, the user will have to remember a pin code and a password, adds bit more difference than private/public passphrase.
Using the private passphrase would not be an issue UX or security-wise. It could be turned on as an optional feature under settings if the user wanted the added security.
However, it's not possible to just turn on this feature with the current dcrwallet public passphrase implementation without also providing a false sense of security. The software may refuse to open the wallet file, but it is 100% possible to use custom software to search through the wallet and discover all relevant transactions and the wallet's balance.
IMHO, it's not worth the time and effort to make the necessary changes to dcrwallet to make this feature secure. Instead, we could direct users to use the encryption features built into their OS (e.g. encrypted files on Windows or encrypted disk images on macOS) and point Decrediton at the encrypted wallet files. This is not as great of a UX, but does provide better security and allows us to work on more pressing issues.
This came up again during a discussion about authenticating the gRPC client, which we should begin doing as the individual account passphrase handling becomes too unwieldy otherwise. Placing an encrypted client certificate privkey on disk and decrypting it at application startup would prevent the use of decrediton (but not dcrwallet) until the passphrase can be provided. Doing this would make a startup passphrase non-optional. An alternative to this is for the dcrwallet child process to communicate the necessary authentication information (the cert itself, probably) so that only that parent process can communicate with dcrwallet and no other applications on the user's computer.