Creating a password in Bash
Asked Answered
T

4

9

I currently have a password that is being generated, that is a hash of the date. I'd like to increase this generated password's security, by adding in some uppercase, lower case, numeric, and special characters, all to a minimum length of 10 characters.

What I currently have is below. As you can see, it assigns the output to my PASSWORD variable.

PASSWORD=$(date +%s | sha256sum | base64 | head -c 15)

I'm unsure if I can do this inline, or, if I need to create a function within my bash script to suit? Is that even possible?

Many thanks in advance.

Tareyn answered 5/6, 2017 at 20:7 Comment(4)
I suggest to install and use pwgen.Clavicytherium
What you currently have is very weak because of lack of entropy. The entropy is equivalent to the data. This can easily be brute forced. The answer from Cyrus below uses a much better source of input entropy: /dev/urandom.Euratom
See also: #30948373Krawczyk
Strength of password would increase if you increase its length, even if you don't increase its underlying alphabet. For instance, a password that is 50 characters long, which is composed of all the same characters, is a strong password.Tottering
L
20

With tr and head:

password=$(tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10)

echo "$password"

Output (example):

k?lmyif6aE

tr reads bytes via stdin from Linux‘ special random device /dev/urandom and removes all bytes/characters but A to Z, a to z, 0 to 9 and !?%=. tr sends its output via stdout to head‘s stdin. head cuts output after 10 bytes.

Linus answered 5/6, 2017 at 20:18 Comment(2)
I had to add LC_ALL=C in front of the tr command to avoid getting Illegal byte sequence errors. For example: LC_ALL=C tr -dc 'A-Za-z0-9!?%=' < /dev/urandom | head -c 10Justinjustina
Creating a password seems like one time when you should use /dev/random not /dev/urandom (because it is worth waiting for a little entropy if needed).Armenian
A
6

Or you can just use openSSL rand to generate the passwords:

PASSWORD=$(openssl rand -base64 10)

The above command for example will generate a string of 10 characters in base64.

Aitch answered 4/4, 2021 at 23:29 Comment(0)
M
0

Expanding a bit on @Cyrus' answer here's an alternate version I've settled on after dealing with a lot of passwords in a lot of contexts:

# Generate a url safe password.
password() {
  local length=${1:-"10"}
  cat /dev/urandom | tr -dc A-Za-z0-9~_- | head -c $length && echo
}

This uses only characters that don't need to be url-encoded and that are easy to select and type, and still has about 60 bits of entropy which is plenty for most purposes (I actually use a default length of 20 which has 120 bits of entropy, but I can't make an honest argument that that's necessary for security).

I also have the following:

# Generate a url safe password that:
# - begins with a letter, and has at least
# - one uppercase letter,
# - one lowercase letter,
# - one digit, and
# - one special character.
stupid_password() {
  while :
  do
    local pass=$(password "$1")
    [[ $pass != *[~_-]* ]] && continue
    [[ $pass != [A-Za-z]* ]] && continue
    [[ $pass != *[A-Z]* ]] && continue
    [[ $pass != *[a-z]* ]] && continue
    [[ $pass != *[0-9]* ]] && continue
    echo "$pass"
    break
  done
}

The filtering process is inefficient, but still essentially instantaneous. The passwords are less secure, but will work on websites that haven't read the NIST guidelines on password complexity

Monthly answered 15/11, 2022 at 17:3 Comment(1)
I should say that the filtering process for stupid_password is essentially instantaneous for lengths greater than 5. Passwords of length 4 or 5 can take a noticeable fraction of a second to generate, and, of course, for lengths of 3 or less stupid_password will run forever.Monthly
B
0

Here is a @Cyrus based answer with better entropy and multiple passwords in one line:

for i in $(seq 1 5); do echo $(tr -dc 'A-Za-z0-9!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~' < /dev/urandom | head -c 20); done

It will generate five 20-byte passwords.

egS<Fp]Y,G>fj@(z1TeB
i^B/juv$%,hJ.tSJzZ=(
te<I&9-/[Wq2,jjd[8fO
t6o"]vmV!arLowG*VCW,
zWiRZuH}q=PfX6Tk++>5
Benefield answered 28/7 at 19:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.