Hacker News new | past | comments | ask | show | jobs | submit login
Clever uses of pass, the Unix password manager (vitalyparnas.com)
271 points by smartmic on Dec 16, 2021 | hide | past | favorite | 148 comments



`pass` was written by Jason Donenfeld, the developer who gave us WireGuard.

It's is a bash script that makes it convenient and easy to use gpg2, the OpenPGP encryption tool. Frankly, I'm kind of shocked at how difficult it is to use the gpg2 command line utility. Clearly it's an extremely powerful tool, but it's written with the assumption that the user has a very deep understanding of how encryption and key signing work. To use `pass` effectively you should have a basic understanding of encryption, but unlike gpg2 you don't need to dedicate a week to grok the manpage.


I wrote a tool called hunter2 [0][1] which is very similar but uses PKCS#11 modules, which may be more common than GPG since the entire US Government uses them.

[0] https://chiselapp.com/user/rkeene/repository/hunter2/ [1] https://github.com/rkeene/hunter2 (mirror)


Love the name. That alone is genius, never mind all the work you've put into the tool itself.


i'd love to see the genius. what makes it so clever?


Mentioned farther in the thread, but it's based on this: http://bash.org/?244321


How do you know my password?


Just in case anyone doesn’t know the reference:

http://bash.org/?244321


I don't, I just copy and pasted the stars. you see "hunter2" but I see "****"


thats neat, I didnt know HN did that


I found it on a sticky note beneath your mouse pad ;-)


Haha, nice. I’m a happy Password Store user of some 2-3 years, but I starred your repository - very cool idea to use PKCS#11 modules.


As much as I love Jason Donenfeld's work, I tried to use pass and the gpg requirement just rubbed me the wrong way. It's basically just gpg-encrpyting a text file and unlocking that along with some wrappers for basic password manager functionality (I guess most important is clipboard functionality and clearing it automatically after some seconds), but somehow that seems like a weak point to me. It's a whole lot of reliance on one extremely bloated suite of applications when I feel like something standalone and about as compact would be better somehow.


As a user, I also often feel like `gpg` brings a lot of annoying accidental complexity to `pass`, (like the need to "ultimately trust" keys before they become usable) but on the other hand it enables integration with hardware tokens like Yubikeys and in extension mobile devices (via openkeychain) that as far as I know wouldn't be possible with a more modern age-based backend.


>like the need to "ultimately trust" keys before they become usable

Did you have to do that manually at one time? All the keypairs that I make start out that way when created.

When creating a keypair for pass all you have to do is generate the key using defaults while remembering a bit of the user ID to give to pass.


Yes, every time I want to set it up on a new device I have to import and trust all public keys that it should encode to; and if that device gets its own gpg key then that key also has to be distributed to and trusted at all prior sites. Which isn't very often, but still somewhat regularly (ie. new laptop, new yubikey, formatted hard drive, etc.)

I think it would be a great addition if pass could actually automate this by storing all relevant public keys internally.


Ah, yes that is a nuisance. GPG has the "--export-ownertrust" and "--import-ownertrust" commands to make that sort of thing less tedious.

In general I think you are supposed to only have a one or a few "ultimately trusted" keys and then distribute that trust by signing the rest. So once you change the trust on one key the trust distributes automatically.


I had to do it when importing keys on another device


Yep the integration with Yubikey is amazing. Both on mobile and desktop <3



SSH has included file encryption for a few versions now, and iirc supports yubikeys — probably would be more useful a backend than age.


> SSH has included file encryption for a few versions now

Mmm. I don't think so. Recent OpenSSH includes file signatures not encryption.


Ahh, you are correct, I misremembered.


Besides that, pass leaks metadata.

If your passwords are the only part of your password manager you think are secret, then you're probably not considering the utility of an enumeration of all your network handles. Mine aren't very interesting, but I wouldn't post that on GitHub, even in a private repo.

I love pass and use it. But when I need to carry my password database around, I don't rely on pass alone - I throw the pass database in a Veracrypt container. That way if my flash drive is stolen, it's just an encrypted blob.


There's also the pass-tomb extension [0] which stores the directory in a tomb [1].

[0] https://github.com/roddhjav/pass-tomb

[1] https://www.dyne.org/software/tomb/


Besides pass-tomb, there's also pass-coffin which doesn't need to rely on a 3k+ line ZSH script. I'll add support for using age and signify in pass-coffin soon.

https://github.com/ayushnix/pass-coffin


A few pass-related projects are working on an age[1] backend in addition to gpg. I think gopass already has support for it.

[1]: https://age-encryption.org/


Here's one I have been playing with success.

https://github.com/chrisswanda/passage


Correct. Gopass has very early age support. It fully works but the UX is not great (yet).


Oh dammit. I have stopped using Gopass and rewrote pass just for that reason - missing AGE encryption. At least I have learned something new and I feel I have better UI - fuzzy finder instead of their TUI. However, big kudos to Gopass team for awesome work and really useful tool.

Before I start working on next project... Do you recognize any mobile app, which could replace PasswordStore app for Android [0] but with AGE support?

[0]: https://github.com/android-password-store/Android-Password-S...


Android Password Store itself is keen to add age support[1], but I don't know of anything usable right now. You could probably use gopass in termux in the mean time.

[1]: https://github.com/android-password-store/Android-Password-S...


Oh, that's an awesome news. Thank you!


> missing AGE encryption

I am just curious. What makes AGE backend better than GPG one?


As yepguy mentioned AGE is simpler. I can also mention few things:

- It works smoothly with SSH keys (generated from ssh-keygen), which are perfectly recognized by possibly any developer.

- No need for external client, such as GpgWin/Kleopatra for Windows.

- Embed-able in Rust[0] and Go[1] (there are libraries), no need to call `gpg --decrypt ...` from the command line.

- Encrypted files by pass and keys are smaller. I guess it is thanks to ecliptic-curve encryption.

[0]: https://github.com/str4d/rage

[1]: https://github.com/FiloSottile/age


Age is much simpler to use in nearly every way, whether that's interactively (keys are just files!), in scripting, or in implementation.

I'm still sticking to gpg for the foreseeable future, but between age and sequoia[1] I'm hopeful that things will soon be much easier to use.

[1]: https://sequoia-pgp.org/


I get what you’re saying but it’s just different philosophies no?

Seems like pass wants to use the Unix philosophy of “do one thing well” so it relies on gpg for encryption instead of rolling its own.


FWIW, adding support for age in pass is listed as one of the goals of age. I'm considering sending an upstream patch in pass to support age and signify as well.


I don't know why, but I usually find the usability of anything crypto-related terrible like ssh or managing certificates. Granted I have no idea about security but I would say that I have some knowledge of computers, I use 2FA minimum everywhere, I use VPN almost daily, I ssh into machines frequently, I use a password manager, I update my software and I'm picky about what I install. You get the idea. And yet I dread having authentication problems, my only resort googling to see what other poor souls managed to do. I think some part of it is part of the nature of the problem since you have to assume some of your users are malicious but a good part is just not caring, like if you don't know what the problem is you should not even be close to a computer.


I wish someone would mint a user-friendly GPG wrapper for signing releases and quorum-based publishing. Dealing with raw GPG to sign releases is doable but a pain. And we need quorum publishing to guard against supply-chain attacks.

But simple and user-friendly UX design is hard. As a user of `pass`, I'm grateful for what I have.


For the signing problem, both signify (and its clones) and modern OpenSSH (ssh-keygen -Y) do what you want today without all the baggage of OpenPGP, obviously that would mean explicitly choosing to migrate off OpenPGP signatures, but that does not seem unreasonable.


I just looked into signify, and I read this:

https://www.openbsd.org/papers/bsdcan-signify.html

> There are no key servers for signify. No web of trust. Just keys.

I'm not sure how that would work for quorum publishing, which guards against any single set of credentials being compromised by requiring multiple trusted signatories. The idea is that packages are signed by multiple identities, and if as a downstream user, you trust enough of those identities to form a quorum (2, or 3, or some score-based criteria), then you consider the release trustworthy enough to accept automatically. (The underlying theory is just multifactor auth.)

Downstream users need some way of determining how to trust keys, and that mechanism should be decentralized. This seems to be at odds with the priority the BSD authors place on key rotation:

> After each release of OpenBSD, we generate a new key pair for the release after next. That's plus two. For example, after 5.6 was released, keys for 5.8 were generated. This way, the 5.8 keys are then included in the 5.7 release. So, if you upgrade every release, you will have an unbroken chain of keys back to your initial installation.

So it sounds like there's a single set of keys for each release, which has to be kept safe. I'm sure that the OpenBSD folks take great care, but the idea of quorum publishing is to require multiple factors so that an attacker has to compromise multiple identities to spoof a release.


For the curl command though written like it won't show up in history, this will still show up in process parameters

To fix this as well pass it into curl as a config via eg: curl [...] -K- <<< "--header auth:$(pass mysecret)"


And this matters a lot because history is normally only accessible to the current user (and root), but process command line arguments are normally accessible to all users.


I've long thought that was a general problem. Why should I see the command line arguments from other users' processes?

What if non-root could see their own processes in detail, but only the program name for other users' processes?

Would that break a lot of other things?


You can do this by mounting procfs with the hidepid= option. But it breaks systemd when enabled system-wide: https://github.com/systemd/systemd/issues/12955

Individual units can opt-in to this behaviour with the ProtectProc= option though. But I don't think there's currently a good way to apply it to users' interactive processes.


Take a look at the `hidepid` option which is available to the /proc filesystem these days:

https://www.cyberciti.biz/faq/linux-hide-processes-from-othe...

Biggest surprise is that people can't run top/ps to see where load is coming from, but that aside I never noticed any particular downsides.


Just try to change it by yourself: https://www.cyberciti.biz/faq/linux-hide-processes-from-othe...

sudo mount -o remount,hidepid=1 /proc


Hi, great question. Have not seen it being enabled break anything so far (only some cross user invouse written process monitoring scripts). Linux has a flag for this for the /proc mountpoint: hidepid=2


Most other users nowadays are likely to be your webserver, your application process, your database, your crawler, and a myriad of other long-running processes.


> What if non-root could see their own processes in detail, but only the program name for other users' processes?

At which point you might as well ask why do you need to see other users processes at all? And indeed, that is an option in grsec. I don't think it causes any major breakage, but there are probably some xkcd #1172 sort of things that break.

edit: apparently there is nowdays also options in mainline for that too: https://pipo.blog/articles/20130930-hidepid-process-hiding and also possibly with selinux?


curl -H/--header itself also takes a file name prefixed by @, including - for stdin. So you could go curl -H@- <<<'API-Key: Foobar', or if you need to specify multiple sensitive headers, curl -H@<(echo API-Key: Foo) -H@<(echo Pre-Shared: Bar)


<() is a bash extension and won't work in another `sh` like dash.


I'm shocked no one mentioned passmenu, a secret script that comes with pass located in usr/share/doc/pass/examples/dmenu/passmenu

Bind this script to a keybinding, and it will load all your passwords into dmenu and let you type the first few characters of a website name, then copy the password to the clipboard. No CLI needed.


It's actually a separate package on Fedora called passmenu. Maybe because dmenu is not standard for Fedora users by default.


Second that. passmenu is very useful, although most of the time I use Chromium or FF plugins for that.

Also, Password Store by Harsh Shandilya on Android is a wonderful little tool. Too pity is has only two sponsors on Github.


Using single file for single password entry is very good idea. It's far better than any tools that opens the whole password database at once (KeePass, LastPass, Bitwarden etc).

Reason is that you can use e.g. YubiKey to unlock individual entries on touch, this means that you can't lose whole password database on ransomware attack, (unless the ransomware has been there for a very long time).

Filippo Valsorda wrote about this: https://blog.filippo.io/touch-to-operate-password-store-yubi...


If you entire encrypted life is stored on a single computer with no backups you really should not be worried about ransomware and start worrying about things that will actually happen, like having your laptop stolen, or accidentally deleting something, or needing to replace your storage device.


This is still susceptible to ransomware. Ransomware will simply encrypt over each file with its own key, regardless of if the file is already encrypted or not.


Backups is of course required. I was talking about Ransomware which also enters your password database and steals the passwords in order to do more harm.

With YubiKey you can make the GPG private key on offline machine and upload it to YubiKey. This way you can always have a offline backup of your private key, and thus you can backup your password database too.


The term “ransomware” is never used to describe malware that steals passwords, thats the point of confusion.


It also has a few downsides: Adding a new key requires re-encrypting every entry. Touching your yubikey hundreds of times gets old, fast.


If you are using GPG keys and have the master key backed up somewhere you can fairly easily use that on an offline machine to add the new key to the full batch of password files without needing to perform a million button presses.


Been there and done that. People are backing up those keys, right?

Could also disable the touch to decrypt feature while you performed the rekey?


I hope people back up their GPG keys (and test their backups! My subkeys on the yubikey expire annually, forcing me to validate my master key backup at least once a year).

Disabling touch is another option if you need to do a large batch of operations and are comfortable that your machine is secure.


You probably shouldn't be able to disable touch. If you can disable it then malware can disable it.

I'd highly recommend using the `fix` option instead of `on` to make sure it can't be disabled.


Yup. My backup key (the one that doesn’t travel with me) doesn’t have the touch policy and I use that for any bulk operations.


I'm not sure I follow. Adding a secret is done with your public key, so no need to even touch the yubikey to do that. And the idea is each one is a separate file. So, adding does not impact any other file.

Edit: oh. Adding a new key, not password. I see how I misread.


Touching? What? I did this recently and it's very simple thanks to pass init. I now have two keys, my old one and my new one that is on my yubikey.


Did you have our key on a yubikey and that yubikey set to require a touch for every operation?


No I wasn't even aware of this feature.

I just enter my pin once and it works until I pull it out.


Here's a script that will set that mode, in case you'd like to use it. It prevents someone/malware from being able to use your key after you've unlocked it. For example if you hacked my computer and tried to use it to ssh to another machine you'd be unable because you'd need me to tap the key.

I'd suggest trying 'on' before 'fix', but then switching to 'fix' for the extra security it provides.

https://github.com/a-dma/yubitouch


The article doesn't mention how well `pass` integrates with `git`. Once you do that, you get revision history, you can push it to a private repo (github, gitlap, etc), and keep your passwords in sync across multiple devices


On Android the app which supports pass+git is called 'Password Store' and can be found on F-Droid: https://f-droid.org/packages/dev.msfjarvis.aps


For those interested in pass for use in shell script based contexts, you may also find encpass.sh (https://github.com/plyint/encpass.sh) useful. This is a simple tool I wrote (a while ago now) to encrypt/decrypt secrets and store them in a manner very similar to pass, except it uses OpenSSL instead of GPG. Since it is also just a shell script and it's only real dependency is OpenSSL, then it can be used in a wide array of environments where installing additional software may not be an option. It also has hooks in the code to write your own extensions, which can be used to add features or utilize an entirely different backend instead of OpenSSL. Check out the Keybase extension as an example. (https://github.com/plyint/encpass.sh/blob/master/extensions/...)


The stdout from `pass` is awful, even for copy-pasting. OTOH, gopass [1], an otherwise 100% compatible drop-in replacement does the job much better and has some neat collaborative features as well.

[1] https://github.com/gopasspw/gopass


Wow, I just tried it and found `gopass show -o ___` works perfectly to scripts that want just the password without any null bytes or newlines in it. You've converted me. Thank you for mentioning it, I never thought to look for a compatible drop-in.


With chezmoi you can use pass to store secrets in your dotfiles, for example if you want to set a secret API token in your ~/.bashrc you can use:

  export SECRET_API_TOKEN={{ pass "api/token" | quote }}
For more info see https://github.com/twpayne/chezmoi/blob/master/docs/HOWTO.md... and https://github.com/twpayne/chezmoi/blob/master/README.md.


What is the `quote` command that example pipes to? Seems handy but unsurprisingly hard to search for.


In this example, `quote` is a function from sprig [1] which chemzoi uses with Go's text/template language [2].

[1] https://masterminds.github.io/sprig/strings.html [2] https://pkg.go.dev/text/template


I think it's this? I found it by googling "shell quote command".

https://askubuntu.com/questions/354915/quote-command-in-the-...


Also note that `printf "%q"` is an alternative to this.


You could also use secret-tool for this, which is compatible with many tools that support the secret tool, I use keepassxc for example.


Recently used pass to share passwords between colleagues (3 in total). Files are encrypted against three different GPG public keys and shared via Git.

Works well enough for us.


Might as well link this blog[1] that helped me recently when I created a new GPG key for my yubikey and wanted to re-encrypt all my passwords for two keys.

1. https://medium.com/@davidpiegza/using-pass-in-a-team-1aa7adf...


For teams there is also gopass (https://github.com/gopasspw/gopass) which is compatible with pass I believe.


Hardware U2F to unlock would make this my dream.


If your goal is to force a touch to decrypt passwords, https://www.palkeo.com/en/blog/perfect-password-manager.html works. You can keep the GPG private key on a Yubikey and require a touch to decrypt.


I use YubiKeys setup for gpg with pass, so unlocking the keyring requires both a yubikey and a PIN, but I haven’t figured out how to do the U2F part.


FYI for those interested in CLI password management, there is a pretty good CLI for LastPass called lpass that even supports your Yubikeys.

https://github.com/lastpass/lastpass-cli


I wrote a cheatsheet[0] for gopass, which I've been using with different teams and personal with great success. It's the same as pass but with support for multiple stores.

I'd like to see something similar but with age support .

[0]: https://woile.github.io/gopass-cheat-sheet/


I use pass along with passff and my yubikey for gpg decryption of the password store and gpg-ssh syncing from my home git pass db. Works great


passff and other tools like them scare me too much. That browser extension has too much power. All it would take is the author to sell it to some bad actors (or turn into one) and a lot of people will be having a very bad day.

Pasting my password into a form isn't that bad, and it feels far safer.


I use a couple of little scripts to do something somewhere in the middle that I'm happy with:

`fzf-dmenu` spawns an alacritty window running fzf over given input.

`pass-dmenu` calls the former with available password names; takes the result (if any) and decrypts & types it with `pass show $result | xdotool type --file -`.


(And if it's not obvious, that's bound to a keypress, so from the browser I just hit F4, type e.g. 'hn<CR>' and my password is entered into the focussed input area.)


Some distros package browser extensions, so you can install them via your regular package manager. For example arch packages firefox-extension-passff (I haven't personally used it though)


You can disable automatic updates for the extension, download it manually, and inspect the XPI file before installing it.

Instead of clicking "Add to Firefox", you can right-click and "Save Link As..."


Docker supports a credential-helper module[0], which supports 4 different backends for fetching the docker registry credentials: osxkeychain, pass, wincred, and secretservice.

pass lets you use GPG-smartcards, and many of those (such as Yubikeys) will let you enforce touch-policies for signing/encruption.

As a combination of both these however, I must touch my Yubikey every time I pull a new docker image.

Another cool use-case is that I use the terraform-pass-provider to save secrets for my personal terraform project.

[0]: https://github.com/docker/docker-credential-helpers


That's quite ... Clever. Now I can version my mbsyncrc and even my shell history without worrying about secrets leak.


Be sure to protect those secrets though -- see eg peer comments about process params (made shortly after yours)


Regular gpg does have a --passphrase-fd argument that's nice for this sort of thing. Where you can specify which file descriptor the passphrase/password is coming from. Very handy for integrating with scripts.


Another useful thing to store as `pass` secrets is credit card numbers / parameters.

This makes it easy to fill in card info online using the same password tools you're already using (passmenu, rofipass, etc.), without needing to go find your wallet, or rely on your browser's form auto-fill database (and worry about hidden fields attempting to exfiltrate that auto-fill data).

I'm tempted to use `pass` to store TOTP seeds as well, but this seems like a bad idea because you'd be putting both factors in one place. Maybe a separate pass db stored offline or something...


At a previous job, I set up all our Kubernetes secrets such that their canonical location was in pass; Creating or updating them was a simple shell script:

    kubectl create secret generic -o yaml --dry-run \
        --from-literal "foo=$(pass show foo)" 
        foo | kubectl apply -f -
I was very pleased with it - It was simple enough for developers to use where necessary, easy to distribute passwords, and worked very well.

The next guy ripped it out and replaced with Vault and none of the passwords have been rotated since.


I also use this for OTP tokens instead of my phone!

https://github.com/tadfisher/pass-otp


One thing I love to use pass with is direnv. The problem direnv solves for me is: how can I have persistent local config/settings in a shared repo without having to push code? Invariably at work there is always the 'shared access credentials to third-party services'. Usually you just throw these in a .env file. This leaves them on your drive in plaintext.

Instead, stuff the creds into pass, and since dotenv leverages bash, you can put substitutions in your .envrc file. Bonus, now that the creds are in a personal secured repo, you don't have to go hunting for the creds every time you want to spin up a new dev machine. (you do unfortunately still have to migrate your .envrc, I tried writing git tooling to make it easier but I could never find a convenient place to store them. I have ideas to extend git to try out the next time I want to iterate on this)

This does require your app to be properly configurable with environment variables, meaning if an envvar is present, it should override all other settings. Envvars don't get set by accident so they should be treated as the ultimate settings. This is usually the case with most frameworks but I've run into Node apps where this wasn't the case. Maddening.


I think use of the copy buffer is the weakness of pass. Can't it be read by any process?


This is a very good point about infosec that a lot of password manager users overlook. Me included.

In wayland you can pipe the password into wl-copy -o so it will only be pasted once then disappear.

In Xorg you'd need a callback after running pass that runs xclip -i /dev/null some time after the password is copied.

There is no good solution to this in Linux that does not involve discipline.


The clipboard? How well it's protected varies by distro, X11 vs Wayland, etc.


In my ansible.cfg I have:

  vault_password_file = tools/vault.sh
In my tools/vault.sh I have:

  echo -n $(pass infrastructure/ansible-vault)
This lets me store my ansible vault master password for managing my personal infrastructure inside pass. I like it.


Ansible also has a collection that allows to work with pass's password store directly[1]. Have been using it with a dedicated pass repo for a while now, the PASSWORD_STORE_DIR variable can be loaded through direnv when entering directory with ansible playbooks to separate infrastructure credentials from user ones.

[1]: https://docs.ansible.com/ansible/latest/collections/communit...


been using pass for more than 3 years now never had an issue, great CLI tool


I still really like how it makes random passwords given a permitted character set. It uses tr -cd to read only matching character bytes - discarding any others - from the random device. If you instead try to be less wasteful in turning random bytes into characters from the chosen set, you are in a sticky situation very quickly where your passwords might be less random than they should be, whereas bytes from the random device are cheap, so just throw away all the ones that aren't suitable and get more. So simple and yet I'm sure it wouldn't have occurred to me.


If you have an M-sized alphabet and you need an n-character password, why not just take ⌈log₂ Mⁿ⌉ bits and interpret it as a number in base M? That seems even simpler to me.


Let's try it.

For example I should like a 1-character password, from the alphabet of A, B and C.

So that's 2 bits. We read two bits (awkward, the random device is of course byte oriented). Now, we have a 2-bit value and we're trying to pick A, B or C. But what do we do with the 4th possibility from our 2-bit value?

We could decide too bad we'll treat it as A (or B, or C) anyway, but now we've introduced a non-random bias to our supposedly random password.

The non-horrible option is to throw away this possibility and read two more bits hoping for a different outcome. The exact same algorithm pass uses, except you've added the extra complexity of reading less than one byte at a time from the device...


With a non-trivial (= much more realistic) length of your random number, how do you ever lose more than a fraction of a bit of entropy this way? Let's say you want a 16-character alphanumeric (a-zA-Z0-9) password. log₂ 62¹⁶≈95.267. Let's say you pull 96 bits and ignore the imbalance. Then you have 2×62¹⁶-2⁹⁶=16116640899382729306982711296 options with a probability of 2×2⁻⁹⁶ and 2⁹⁶-62¹⁶ options with a probability of just 2⁻⁹⁶. That comes out as around 95.203 bits of entropy, which isn't significantly different from 95.267. What obvious fault am I missing here?


> What obvious fault am I missing here?

Well, let's begin with the fact it's worse. You argue it's not "much" worse, but it is clearly worse not the same. Under 'pass' all passwords conforming to chosen rules are equally likely, under your approach some are twice as likely as others.

But then the other characteristic is simplicity. Using 'tr -cd' is, by my counting, five characters. How big is your best implementation of this supposedly "even simpler" but worse solution?


> Under 'pass' all passwords conforming to chosen rules are equally likely, under your approach some are twice as likely as others.

But they're passwords. At most half of the passwords will have different probability than the rest which means that you're still left with a staggering number of un-brute-forceable passwords. Two to the power of ninety nine is practically indistinguishable from two to the power of one hundred.

By the way, if you're still obsessed about completely equal probabilities here, you can just drop the whole sequence of bits if it's larger than the number of alternatives when interpreted as a binary number and fetch a new one. It seems to me that the expected value of number of bits consumed for such a process won't exceed twice the number of bits that are technically necessary (because the probabilities of individual numbers of attempts are a geometric sequence with a factor of at most 0.5 summing to exactly 1, which would have an expected value of 2), which is around 12.5 bits per character. With a filtration like tr -dc "0-z" mentioned below you'll consume roughly 27.3 bits per character on average. So "better" is a subjective term here; one solution may be simpler to write in a shell command line, another consumes much less entropy. If you're deciding what to do, you need to weigh your criteria properly if you have more of them. You may very well have different criteria than I do; that happens.

> Using 'tr -cd' is, by my counting, five characters

I probably wouldn't use this in the first place because it requires a subprocess and a binary that I might not have on some computers. So by my counting this could be hundreds of kilobytes of extra code. Division with a remainder is most likely something you already have in your standard library regardless of whether you use it or not.


> another consumes much less entropy

To the extent that it could mean something to "consume" entropy from the random device they're both outputting the same size of password and so they're consuming roughly the same amount of entropy. Assuming the random device works as intended this would be a distinction that makes no difference anyway.

> a binary that I might not have on some computers

A binary that's included in the Linux Standard Base. Which computers don't you have it on?

> this could be hundreds of kilobytes of extra code

More like a few dozen kilobytes, although of course on tiny Linux systems it's bundled into something like busybox so much less.

> Division with a remainder is most likely something you already have in your standard library regardless of whether you use it or not.

The shell, which is what pass is written for, does have division with a remainder, but it cannot do this operation on 96-bit integers. So now you've added another constraint "rewrite this software in a language which has 96-bit integers, or more if longer passwords are allowed" [Hint: Longer passwords are very much allowed in pass]

So far what you've achieved is to show that this is trickier than you thought, yet produces worse results. Again, this is why I like what Jason did here.


> A binary that's included in the Linux Standard Base. Which computers don't you have it on?

I'm using some Windows computers. But for example I can use (and often do) a dumped SBCL binary on them just fine, even on those where I can't install anything.


This is "simpler" because it's a one line shell snippet:

    tr -dc "0-z" < /dev/urandom | head -c10


It means password generation takes variable time; this:

• opens you up to timing attacks on your PRNG (unlikely to be a problem in real life, but you never know)

• might run forever


A successful timing attack against /dev/urandom would be a major bug that you could expect to be highly prioritised by the Linux team.

That is, for most people it is well outside the attack surface that they need to care about.


The timing depends on your charset. You may not want to tell it to everyone on the street, but it's not something you need to keep secret either.


It has probability 0 of running forever


Assuming a perfect RNG, but PRNGs don't have infinite state. So it's either impossible, or has a finite probability, with a finite probability for each of those cases, for an overall finite (non-zero) subjective probability of it running forever (in ideal program-space; obviously it will never run forever in real life).


No, you don't need a perfect RNG. You need anything that's not completely horrible.

Remember, we're not trying to read a whole password from the device, just one matching byte at a time. So, even if our password character set is a single character (pass will let you do that, but obviously you should not use such passwords in real life) we're talking about statistically 1 out of 256 bytes matches or else our PRNG is useless.

You correctly observe that the PRNG has finite state, but its state isn't so tiny that it only emits a handful of the 256 possible bytes before getting back to where it started, nobody would use such a busted algorithm.

RC4 is considered broken and unusable because the keystream is biased and thus distinguishable from random - to the extent that if you read a few million bytes from it you can detect the bias, but you're asking us to imagine that the random device has a PRNG many orders of magnitude worse in order for this to have any effect at all.


> You correctly observe that the PRNG has finite state, but its state isn't so tiny that it only emits a handful of the 256 possible bytes before getting back to where it started, nobody would use such a busted algorithm.

If the PRNG always loops through all possible states, then sure. But if there's a possibility, however small, of it getting stuck in a small loop, very rarely?


> But if there's a possibility, however small, of it getting stuck in a small loop, very rarely?

We already went around this particular "small loop" so I'm guessing you aren't learning anything from repeating it. That would be a lousy design for a PRNG, so, nobody does that.


/dev/urandom isn't pure mathematics, it consumes hardware entropy.


But a nonzero possibility of running longer than x for any x>0

;)

In practice, it doesn't matter, I agree.


I don't understant what you mean here. Why would the passwords be less random?


Yeah. I think it might be the tool that's given me the most quality of life per line of code :-)

Stellar. Absolutely stellar piece of software. Always does exactly what I want it to, never gets in my way ever!


Is there a way to use it with the D-Bus org.freedesktop.secrets service?


Would love to see more examples of how to use this across teams - any pointers?



I wouldn't recommend it unless you like GPG key management. (re)encrypting passwords for all your team members is a real pain. We recently switched from pass to BitWarden and it's been far more convenient.


I use pass with Emacs, using this package [1], and it's very nicely integrated and useful.

[1] https://melpa.org/#/pass


Check out sicuit, also GPG based. https://codeberg.org/simonrepp/sicuit



All great, but I wish `pass` was usable in scripts without having to pipe it through `head -n 1 | tr -d '\d'`


Looks very neat; nice Unix’y solution. Would love this to integrate with Bitwarden which I use on my phone.


Are you referring to Pass? There is... https://mssun.github.io/passforios/

Works wonderfully and with OTPauth also.

Run a bare git repo on your own network and there is no reason to use Bitwarden.

Edit - and for those that are in AWS, you can use pass along with aws-vault to keep your ~/.aws creds in check. https://github.com/99designs/aws-vault


Sadly no yubikey support though - https://github.com/mssun/passforios/issues/42


Is there an equivalent for Android?




there is a pass import pluging allowing you to import bitwardn csv

https://github.com/roddhjav/pass-import

maybe you can "bridge it" with bitwarden-cli via some export/import commands or may as well use bitwarden-cli directly (but i find the pass ui much bettwer than bw cli command)


Thank you..

Just setup isync yesterday. So close to having freedom to move from Google whenever I want


incredible tool, works so well with yubikeys and cross platform. use it and recommend it all the time.


I got stuck at init




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: