3 releases (stable)
Uses old Rust 2015
1.1.0 | Mar 18, 2020 |
---|---|
1.0.0 | Dec 17, 2017 |
0.0.1 | Dec 10, 2017 |
#729 in Authentication
24KB
404 lines
pw
pw
generates passwords statelessly, much like a brain wallet. pw
has
options to insert special characters, to be used in a One Time Pad mode, to
generate passwords based on the current date (for organizations which require
you to reset your passwords every N days), or to use some pre-shared key
material in addition to the user secret to generate passwords. These options
are all available via the command line, or additionally via a config file,
which can be encrypted via the native OS keyring.
Installation
To install pw using a recent version of rust/cargo, do:
cargo install pw
It has a few other dependencies, which are likely installed on desktop systems:
dbus
on Linux (libdbus-1-dev
on Ubuntu)gmp
(libgmp-dev
on Ubuntu)
Analysis
pw
uses pbkdf2
with sha512
to stretch your password, with the supplied
entity as the salt. The result is encoded in base58, meaning that each symbol
in the password has ~5.86 of entropy. By default, pw generates passwords of
length 20, so there are ~117 bits of entropy per (default) password. By
comparison, "correct horse battery staple" is only 44.
Password Rotation
Changing passwords, memorably. pw
offers several features for changing the
generated password for a given salt and user secret combination. For example,
some organizations require users to change their password every 90 days. This
is security theater, but nonetheless, users must cooperate. Using a standard
password generator, users could append a "2" and a "3" ("4"...) to their
password ad infinitum; the problem with this is that it makes some part of the
plaintext input known. pw
uses a novel method of changing the number of
iterations for pbkdf2
based on such inputs. --otp
can be directly used to
change the number of iterations and thus the generated password. --period
and
--date
can be used together to work around organizations who e.g. require you
to change your password every 90 days. --period
alone calculates the password
based on the current date, while --date
allows you to pass an arbitrary date
for which to calculate password.
Adding Special Characters
By default the base58 encoding includes only alphanumeric characters. Some
organizations require special characters in their passwords. Users can add
arbitrary special characters by supplying an argument to --special
. By
default, --special
includes 25 typically allowed special characters.
Salt Recommendations
The salt is of particular importance to generated passwords. A typical suggestion is to use the domain of the entity that the password is for, but the problem is that an attacker who steals usbank.com's password database may just generate a rainbow table for usbank.com. So, some personalized version of the salt is recommended. For example, I might choose tycho.usbank.com. An additional feature (discussed in TODO) would be a global offset for the algorithm, so people could choose e.g. to not use the default offset of 0, but something else for all of their passwords.
Usage
pw
has support for storing a password in the OS native keyring, via
--{get,set,delete}-keyring-password
, so that users don't have to type in
their password each invocation.
There is also X11 clipboard support on Linux via xclip
, so users can pass
--clipboard
to pw, and it will automatically copy the generated password to
the clipboard.
Finally, worth noting is that pw
has support for a configuration file,
allowing for a few other features, which can be configured via
--{get,set,edit,delete}-keyring-config
. For example, users can store OTP
offsets, special character sets, or even pre-shared key material (config key
preshared
, a string) to use for generating particular passwords. Currently
this config file must be stored in the keyring, so it is not exposed to
unencrypted access. Of course, this is not stateless, and pw can function
entirely without this configuration, but it may be useful to some.
TODO
- Encrypt the config file. This is mostly supported if you put the config file in your keyring, so not a high priority, especially given that I've not seen a file encryption library for rust that really jumps out at me.
- global setting for
--otp
to further thwart rainbow tables
Dependencies
~15MB
~350K SLoC