[HN Gopher] GoKey - A simple vaultless password manager in Go
___________________________________________________________________
GoKey - A simple vaultless password manager in Go
Author : krn
Score : 127 points
Date : 2022-07-10 11:56 UTC (11 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| itake wrote:
| Neat idea but doesn't work if your passwords must be changed.
| bachmeier wrote:
| Can't you just add "2", "3", etc. to the start or end of the
| URL?
| aw4y wrote:
| then you need to remember for each domain which "version" are
| you at. imagine for 200 domains...
| umvi wrote:
| How often does this happen? In the past 10 years I've had
| to change exactly 0 of my passwords, let alone 200
| resoluteteeth wrote:
| I'm amazed you've literally never had to change a
| password; while there are plenty of sites that have never
| made me change my password, I find that I usually am made
| to change a password every month or two.
| ThePhysicist wrote:
| Don't want to be too negative but that's a hilariously bad idea.
| Basically the security of the scheme relies entirely on the
| strength of the master password. If a third party every discovers
| that password it can derive all your credentials (current and
| future ones) from that single password and the applicable URL
| (which often can be figured out easily). And if you use a seed
| file with this as suggested in the README you can as well use a
| regular encrypted database, which at least allows you to upgrade
| passwords.
| jtwebman wrote:
| Is this not how crypto wallets work as well for at least most
| of them they come from seed phrases.
| mhluongo wrote:
| New seed phrases are typically 12-24 randomly generated
| words, not user provided... and when you need to "change a
| password" in a crypto wallet, you can generate a new private
| key and move funds.
|
| Check out BIP-39 [0] for more details.
|
| [0] - https://github.com/bitcoin/bips/blob/master/bip-0039.me
| diawi...
| paulryanrogers wrote:
| It's curious watching all these derived password solutions
| evolve. They all end up taking on state, or requiring laborious
| transitions, if either a derived or master secret is
| compromised. Then their sync-free guarantees fall away.
|
| SQRL went through all these things in slow motion. Or at least
| that's how it felt listening to the "Security Now" podcast.
| SloopJon wrote:
| > They all end up taking on state
|
| Note that the recommended operation for GoKey requires the
| use of a seed file. Instead of deriving passwords directly
| from the master password, it derives them from a file of
| random data that is decrypted by the master password.
|
| While it's true that this seed file doesn't require the
| ongoing synchronization that a vault does, it's something
| that you need to have, and to manage with care.
| laurent123456 wrote:
| > While it's true that this seed file doesn't require the
| ongoing synchronization that a vault does, it's something
| that you need to have, and to manage with care.
|
| But even if it rarely changes, how would that file be
| synced in practice? Probably dropped in a Syncthing or
| Nextcloud folder. And if you do that, you may as well drop
| a Keepass file in there, and not have to deal with the many
| problems that this "vaultless" solution cause.
| djbusby wrote:
| So...state with careful management of a secret?
|
| Double plus ungood.
| leetrout wrote:
| I have used a tool like this in the past. Vulnerable to bugs in
| input and output handling and this one looks like it is missing
| features to make it suitable for a daily driver to make it
| conform to restrictive password requirements unless I missed it
| scanning the readme.
|
| Definitely useful for managing key pairs tho
| alberth wrote:
| How does this deal with changing URLs?
|
| Eg Gmail has been over the last decade: gmail.com,
| mail.google.com and now www.google.com/mail
| giancarlostoro wrote:
| I think you forgot googlemail.com as well ;)
| lastangryman wrote:
| I think the URL is arbitrary and doesn't even need to be a URL.
| For example, you could just use "Google".
| postalrat wrote:
| You would either have different passwords for each or would
| need to change your password when switching.
| dcow wrote:
| It's weird to see this from Cloudflare. Is this someone's
| promotion project? Usually the stuff they release is related to
| their product and platform in some way and you instantly
| understand the overarching narrative. This is... not that...
| rather just a neat idea that actually doesn't work in practice...
| It's also pretty trivial. I don't really understand why we need
| another CLI KDF implementation. This is probably a python one-
| liner.
| edf13 wrote:
| What happens when the realm key (e.g.) changes? Example
| Facebook.com to fb.com?
| resoluteteeth wrote:
| This is an idea that people keep coming up with that seems cool
| in theory but in practice doesn't really work.
|
| Ignoring the question about security compared to a normal
| password manager, the biggest practical issues are
|
| 1) Once you need to handle password changes and special password
| requirements (length/containing or not containing symbols), you
| end up having a list of exceptions that's similar to a password
| vault anyway (once you're synchronizing an encryption key and
| list of exceptions you might as well just use a vault-based
| password manager like Pass)
|
| 2) You can't see what sites you have "stored" passwords for
| (since there are no stored passwords). This means it can be hard
| to determine whether you have an account on a given site, and if
| your key is compromised you may not be able to determine all the
| sites you need to change the passwords for.
|
| 3) The password is also tied to the domain, so without a list of
| stored passwords it can be extremely confusing if a company
| switches domains without you realizing it or remembering what the
| previous domain was. Ideally this shouldn't happen a lot but it's
| not as infrequent as you would think among companies that have
| multiple brands if they change their sso system or something. (I
| guess this would also break fido so maybe companies will stop
| doing it if fido really catches on.)
|
| 4) You can't store information other than passwords. This is
| really annoying on sites where you have to create usernames if
| you don't/can't use the same username everywhere. You can put
| this information in the exception file from 1 but the more
| information you put there the less point there is in using a
| "vaultless" password manager.
|
| I did actually use a vaultless password manager for a period in
| the past, but based on that experience I concluded that the
| downsides hugely outweigh any advantages and would not recommend
| that anyone use them.
| ieYp7BpFM8NL7rx wrote:
| In addition to these I also find, personally, that having
| multiple different accounts on the same domain is pretty
| common. If you go to the subdomain/FQDN level, it might be less
| common, but then you have the problems that (a) companies
| change their login subdomain even more often and (b)
|
| With a vault, I can choose whether I want the URL to be matched
| to the base domain/public suffix, to the host/subdomain, to the
| whole path, etc., for each entry. And in fact I do have pretty
| much every option my manager (Bitwarden) offers in use (except
| maybe "regular expression"). Without a vault, you have to
| _remember_ which option you chose, which means you effectively
| have to use the same method for every site (or at least for
| most sites, whatever you don 't log in to often enough to
| remember).
|
| It also causes problems for those companies which have "SSO" by
| using the same credentials across multiple different
| subsidiaries/affiliates on different domains - I'm thinking
| here about United Healthcare, who have sign-in at `healthsafe-
| id.com` for insurance, and at `healthsafeid.optumbank.com` for
| FSA, using the same set of credentials (and yes, obviously this
| is a terrible practice on their part, but you often don't have
| any real choice about using companies with these terrible
| practices).
|
| And it also makes any integration/automation (i.e. at its most
| basic "press a hotkey to inject password keystrokes for the
| current selection") need, as you mention, a list of
| exceptions/mappings (or else to not work for any sites like
| these).
| thiht wrote:
| It also doesn't seem to know about usernames. How do you create
| multiple passwords for a single domain? Does using something
| like username@domain.tld for the realm work?
| ieYp7BpFM8NL7rx wrote:
| > -r ... any string which identifies requested password/key,
| most likely key usage or resource URL
|
| From the readme. So, yes, but then you have to remember your
| username and that you made that site's password as such...
| jwilk wrote:
| You can use any string you want as the realm.
| steeleduncan wrote:
| Yes, I wrote a tool for myself a few years back to do this, but
| abandoned it. 1 was especially problematic for me. To add to
| your list
|
| 5) You have a problem if you need to cycle a password for a
| site either due to some password rotating policy of theirs, or
| a security breach requiring a reset.
| kreetx wrote:
| The config file about password requirements and password
| cycle number could be more semi-public, it's not a secret but
| you'd probably not have it on github either (no reason to let
| people know where you have accounts at; still, it's not a
| secret).
| resoluteteeth wrote:
| But then why not just store encrypted passwords in that
| file?
| judofyr wrote:
| If you find this interesting, you might like the same concept in
| JavaScript/Node.js written ~10 years ago and available in the
| browser as well: https://getvau.lt/
| motohagiography wrote:
| Without a complete read of the code (I wish they wrote up the
| protocol, not having one is a huge red flag, so instead I'll just
| risk being wrong on the internet), this seems like a
| straightforward KDF where instead of storing a master key in an
| HSM, you just remember your master passphrase and each new
| password is a diversification component.
|
| Typically, a protocol like this would have the master key in a
| vault/hsm, and your first user key would be derived from that
| master, and you do derivations from that, and when you need a new
| identity, you derive a new user key from the vault key.
|
| Concievably, we could replace the vault with hashes of just
| really long passphrases that you remember and generate on some
| trusted interface, and then derive new RP site passwords from the
| hash of each long passphrase. Mnemonic password storage
| essentially. What you would usually do is include a counter in
| the authN protocol, so each instance of the session password
| going over the wire has forward secrecy, but that requires your
| relying parties to speak that protocol, where the proposal here
| is just for password management.
|
| I'm sure the people behind this are very competent and clever,
| but again, the problem it solves and how it solves it would be
| more useful than a command line UX and "trust us!" What I can't
| stand about security and some crypto people is they challenge
| people to reason about something without providing the objective
| details of a protocol, and then expect us to trust them when we
| can't reason about it as effectively. I'm merely ignorant, not
| stupid, and asking me to trust something because I can't reason
| about it borders on offensive sometimes.
| onionisafruit wrote:
| Another good reason for a protocol is that there are limited
| places where you can run this cli. If I started using this and
| later needed to access a password from my phone, I would have a
| lot of hoops to jump through.
|
| On second thought, maybe the fact that this only has a command
| line interface is a good indicator that it isn't meant to be
| what I think of as a password manager.
| drdaeman wrote:
| I've skimmed through the source code, so I'll save y'all some
| time.
|
| It's all based on a PRNG, which is based on an AES-256 in CTR
| mode (making it a stream cipher) seeded with a key generated by
| 4096 iterations of PBKDF2-SHA256. PRNG just decrypts a stream
| of zeroes with a KDF-generated key. All standard library
| algorithms, nothing custom.
|
| To generate a password, it builds an alphabet, picks a random
| character from it by reading a byte from the PRNG. It is
| looping until it reads a byte is less than `255 - (255 % max)`
| where `max` is length of the alphabet, then returns `b / (255 /
| max)` where `b` is the byte from the RNG. Basically, dividing
| [0-254] range (255 is never accepted) into equal-length `max`
| pieces and figuring out where it falls. The generated password
| is checked for compliance (i.e. that randomness had produced a
| special character, etc.) and returned if it's good, otherwise
| it loops and tries to generate a password again. Given that RNG
| is fully deterministic, this produces consistent results.
|
| I haven't bothered looking into keypair generation - I just
| woke up, sipping on my "morning" coffee as I'm typing this, so
| I'm kinda lazy.
| lucgommans wrote:
| Ah, another one for my list, and this one from a big vendor like
| Cloudflare!
|
| On my to-do list is a little project that takes many password
| "managers" like these, which are really just hash functions with
| an interface (called "vaultless" here), takes as second input a
| dump of password hashes that nobody has cracked yet, and goes to
| down the hashes list trying the _usual_ password list but running
| it through these "managers"' algorithms first. I wonder how many
| people turn out to use weak passwords as their master key for
| this sort of thing. Maybe this is more clear:
| foreach linkedin_hashlist as hash do foreach
| brainpwdmgr_algorithms as algo do foreach wordlist as
| word do c = algo(pwd=word, site='linkedin.com')
| if c == hash then print(c, word) fi
| end end end
|
| If the --password input for these tools is guessable, an attacker
| can use this to retrieve the key that this tool will generate for
| any website. I can then go on and try likely usernames (I've
| already got one, presumably) on various sites with what I know is
| probably the correct password. A handful of failed logins per
| website don't attract attention, and I'm already virtually
| certain of the login credentials.
|
| This "gokey" does have the option to add a seed file, which would
| make such an attack impossible if generated securely. How many
| people use that option is the question. In the readme the seed-
| file-less mode is labeled as the "simple mode", perhaps that
| sounds attractive to some readers that don't realize the danger
| of the simple mode (kind of sounds like "default mode", when you
| don't want fancy options, just a standard password vault?).
|
| (If someone wants to steal this idea, feel free to pick it up of
| course; the actual work is in the execution as always.)
| stusmall wrote:
| If a password for one account gets compromised is there anyway to
| rotate it without rotating every password for every account I'm
| using this for?
| rossmohax wrote:
| add a suffix to the realm
| aw4y wrote:
| you need to remember all of them
| umvi wrote:
| Google doc
| resoluteteeth wrote:
| Once you need to keep track of extra information like
| that in a google doc, how is that better or more
| convenient than just using a normal password manager with
| a vault?
| umvi wrote:
| It's free, you can print it out and tape it to your
| workstation, etc
|
| The biggest problem with password managers is that you
| become completely dependent on them (and therefore
| completely helpless without them) once you start using
| them. This scenario still allows you to remain decoupled
| from that dependency.
| resoluteteeth wrote:
| If you use a vaultless password manager like GoKey you're
| also going to be "completely dependent on it" (and a
| printed copy of your list and a copy of your key if
| you're using a key rather than a master password) to log
| into anything. Why is that better than being "completely
| dependent" on another free password manager like Pass
| that's just a wrapper around gnupg and git?
|
| In either case you're going to need a copy of the
| software itself and some sort of shared file with either
| a list of password changes/rules, the actual encrypted
| passwords, and a master password or key to log in to
| anything.
|
| Once you've given up on being able to log into sites
| without having a specific program handy and synchronizing
| some sort of data, why not simply store the encrypted
| passwords in the data you're synchronizing?
| umvi wrote:
| I disagree. I use a vaultless password manager and I have
| the metadata for my most common accounts (Google, Amazon,
| etc) memorized so I am not completely dependent on the
| metadata file. The vaultless password manager can easily
| be downloaded anywhere, and could even be manually
| implemented if need be so I'm not completely helpless
| without my phone unlike my PM friends.
| philip1209 wrote:
| There's a lot of skepticism here. But, integrating this algorithm
| with a crypto hardware wallet could be really interesting.
| mhluongo wrote:
| Modern hardware wallets already implement hierarchical
| determinism, and have for a few years. Extending that further
| to do private keys per site wouldn't work on most chains I know
| due to chain state...
|
| Details in BIP-32 [0] and BIP-44 [1].
|
| [0] -
| https://github.com/bitcoin/bips/blob/master/bip-0032.mediawi...
| [1] -
| https://github.com/bitcoin/bips/blob/master/bip-0044.mediawi...
| kasperset wrote:
| This reminds me of https://crypto.stanford.edu/PwdHash One of the
| first "password manager" I used.
| raggi wrote:
| Why is this repo implementing custom (fiddly) rsa code rather
| than using a vetted kdf?
| c0l0 wrote:
| Being able to specify a "super-secret-master-password" on the
| argument vector of the program when invoking it is a Really Bad
| Idea, since, at least for a brief window of time, all logged-in
| users on a UNIX-ish box will be able to see it in the clear in
| the process table...
| crest wrote:
| It can't replace a normal password manager, but the idea has
| other applications and it's nice that they already included
| support deriving a public key pairs from a password and realm.
| Add a zero-knowledge password proof and you've got a useful
| building block.
| emacsen wrote:
| This is a lovely idea, but in practice, has multiple problems.
|
| Firstly, if your password must be changed, maybe due to a data
| breach- you can't change it in your password manager.
|
| Secondly, different sites have different requirements on
| passwords- length, the presence of certain characters, etc.
|
| Thirdly, while low probability, it is possible to have such a
| system compromised, and then passwords could be derived. This is
| no worse than a password vault, but a password vault can be
| changed easily.
|
| A nice idea but not something to use in real life
| Asooka wrote:
| You could store a bit of metadata per password. Like an
| additional salt that you change every time you have to change
| the password, plus any requirements for generating it. Of
| course then it is using a kind of a vault.
| umvi wrote:
| Right but that metadata (like password rules) is pretty much
| public information so it doesn't matter if an attacker gets
| it so it doesn't have to be as secure as a "vault".
| resoluteteeth wrote:
| Once you're assuming 1) you trust your master password or
| encryption key to provide sufficient security to generate
| passwords based on the domain and 2) you have a file you're
| synchronizing that contains metadata for each site like
| passwords changes and usernames well, guess what?
|
| Just go ahead and generate random passwords for each site,
| encrypt them with the master key, and store them in the
| metadata file! Since they're encrypted, the encrypted
| passwords are no longer more sensitive than the other
| metadata in the file and you just reinvented a normal
| password manager.
| umvi wrote:
| The biggest problem with password managers is that you
| become completely dependent on them (and therefore
| completely helpless without them) once you start using
| them. This scenario still allows you to remain decoupled
| from that dependency. You could print out a copy of your
| metadata to take with you on your trip to Europe without
| worrying that you'll be completely hosed if someone
| steals your phone/password manager.
| umvi wrote:
| It has a few drawbacks but also some advantages (namely that is
| way more convenient than a traditional PM and also doesn't
| actually store any passwords)
| blamestross wrote:
| I implemented a personal tool based on the same principle. I
| decided having a config was worthwhile and then you could just
| add a "version number" to the salt. Having a config provides
| the vulnerability of listing what sites you use, but let's you
| add things like a per-website salt.
| archi42 wrote:
| I would underestimate one critical advantage of your system:
| If the site changes their URL for some reason (depends on
| which components you use) you can just look up the old URL in
| your database. Without that, good luck figuring out that it
| was sea.customer-sso.auth.example.com/portal/login.jsp :)
| blamestross wrote:
| This happened when cbs rebranded to paramount
| BeefWellington wrote:
| Calling it vaultless when the recommended mode of operation is to
| use a seed file (effectively becoming your "vault") seems a bit
| misleading. While it _can_ operate in a vaultless mode and derive
| passwords from your master password and site, even they don 't
| recommend that because it's weak.
| bitwidget wrote:
| So if I understand correctly, based on the documentation, if
| someone has the master password and the login url, they can
| derive all passwords without any 2fa/verification? If so, that
| seems like a security flaw...
| nprateem wrote:
| Such a bad password manager makes me lose faith in Cloudflare as
| a brand.
| SloopJon wrote:
| I totally tuned out that this is a Cloudflare repo. Some
| Googling turned up a USENIX slide deck that puts this into
| context:
|
| https://www.usenix.org/sites/default/files/conference/protec...
|
| Whereas the README uses URLs as the realm string, the slides
| uses realm strings like "root-password" or "ssh-v2" to derive
| keys from a seed stored in a UEFI variable.
|
| I think the idea is that you can administer all of your servers
| with one master password, while each server derives different
| passwords locally from its own seed. If a given seed is
| compromised, rederive the passwords from a new seed (or
| reprovision the server from scratch). If your master password
| is compromised ... well, try not to let that happen.
| e12e wrote:
| > If your master password is compromised ... well, try not to
| let that happen.
|
| Good thing that keyloggers don't exist then... :'(
| deletemeplz wrote:
| It doesn't even specify how many rounds of KDF are used in the
| readme. I really hope it's more than the default 4096. For
| reference, using KeepassXC, there's a "benchmark" button that
| finds the number of rounds for a 1 second delay and the number
| of rounds for my computer is in the 50000000 range.
|
| It just takes one compromised password to start a dictionary
| based or other offline attack to brute force the master
| password which would then allow the attacker to regenerate
| other realms.
| jwilk wrote:
| It's 4096 iterations:
|
| https://github.com/cloudflare/gokey/blob/v0.1.0/csprng.go#L2.
| ..
| nprateem wrote:
| It even doesn't matter. Passwords should be regularly rotated
| and encouraging people to use this opens them up to bad
| practices since no one's going to rotate all their passwords
| at once, so they'll never do it.
| mhluongo wrote:
| > Passwords should be regularly rotated
|
| Disagree. I'd even call required rotation a smell.
|
| Requiring rotation leads to people coming up with passwords
| more frequently, meaning they'll likely choose weaker
| passwords. On top of that, regular rotation isn't necessary
| for passwords generated independently by a password
| manager.
|
| The issue here is that there's no way to deal with
| revocation / password changes if a service is compromised.
| nprateem wrote:
| It doesn't matter what you think. If someone's using a
| service that requires it and the tool doesn't allow it
| it's no good.
| mhluongo wrote:
| I responded to that in the original comment. Whether or
| not a service requires rotation (bad practice), this tool
| won't work (can't handle compromised passwords).
| riffic wrote:
| _sees cloudflare as the repo owner_
|
| my interest is piqued, will be looking into this further, thanks!
___________________________________________________________________
(page generated 2022-07-10 23:01 UTC)