Ayak973
Ayak973

Reputation: 454

Bash file: wrong SHA512 hash in while loop

I've created a bash script to hash my user's passwords. These credentials are stored in a file called "usernamemdp.txt" with the following format :

Username1 password1

Username2 password2

My bash script create two output files, with the content :

username1 password1

username2 password2

for the first file, called "username.txt" (the content is the same, with the lowercase username), and :

username1 password1 sha512ofpassword1

username2 password2 sha512ofpassword2

for the second file, called "usernamesha.txt"

Here is the script content:

#!/bin/bash
#set input/output files variables
INFILE="usernamemdp.txt"
OUTFILE="username.txt"
OUTSHAFILE="usernamesha.txt"
#create and/or empty output files
> $OUTFILE
> $OUTSHAFILE
#loop through the input file
while read LINE; do
    #take the first word as username, and lowercase it
    USERNAME=$(echo $LINE | tr '[:upper:]' '[:lower:]' | awk '{print $1}')
    #take the second word as password
    REALPASS=$(echo $LINE | awk '{print $2}')
    #hash the password
    SHAPASSWORD=$(echo $REALPASS | openssl dgst -sha512)
    #output to the first file
    echo "$USERNAME $REALPASS" >> $OUTFILE
    #output to the second file
    echo "$USERNAME $REALPASS $SHAPASSWORD" >> $OUTSHAFILE
done < $INFILE

The issue is that the hashed password is never the one that I expect. When I echo the variables, $REALPASS is ok with no trailing spaces, but $SHAPASSWORD is not good. I've tried to replace openssl dgst -sha512 with mkpasswd -m sha512, but the results are the same.

When I type the hashing command on my console (echo -n bite | openssl dgst -sha512), the output is correct:

(stdin)= 3c71cad6982778650fcecd4f37a34ef4349f6e01adaf3cddcb804856c92096b698411c42c7d68f9d6e380c0b487b4019203956496eaa7cac9ac96fdcf3d63dfd

When I run the script, the hashed password is not what I expect:

(stdin)= 0e73a7f0a2c108e3f29cf3220a464e8cd7f515b99a65d77f1c82696342f77ba20345102a803686a81370b1a48302fc191055e215fa3ca1b0841571c924ff01ee

I'm suspecting a bad usage of echo and $(), but I'm stuck and don't understand my mistake. What am I doing wrong?

Upvotes: 0

Views: 729

Answers (1)

Kusalananda
Kusalananda

Reputation: 15633

In script:

SHAPASSWORD=$(echo $REALPASS | openssl dgst -sha512)

In text:

echo -n bite | openssl dgst -sha512

Notice the missing -n in the script. A newline at the end will make a difference to the digest.

Also, the incorrect SHA512 digest that you mentioned is the digest for

bite\r\n

Not only does it have a newline at the end, but a carriage return as well. This may come from having created the input file on a Windows machine.

I have not looked too closely at the rest of the script, except to notice that it won't cope with passwords that contain spaces due to the way the parsing is done by awk (splits on whitespaces).

I'd suggest you quote your variables, and use printf which has a more consistent behaviour across shells in comparison to echo:

printf '%s' "$REALPASS" | ...

I'm additionally more than a little concerned that you're storing user's passwords in clear text in a text file. There is already a system in place for handling (login) passwords.

Upvotes: 4

Related Questions