Bash read password

Written by: Linuxopsys   |   Last updated: April 6, 2023

It isn’t a good idea to put passwords directly in shell scripts. Whenever we provide a password in Linux, it should either be invisible or asterisks (*) should mask our passwords so that it becomes unreadable. In this topic, we will cover the different techniques of reading password using Bash.

How to read passwords in Bash?

Bash has a built-in utility to read input from the user, named read. We can use this tool directly by using certain flags that come with it. By the help of this command, we can also write a script to take the input letter by letter and convert those letters into * on the fly. We also have a widely used command to encrypt and decrypt passwords, thereby further securing them.

Read without displaying the typed characters

When prompted for the password, bash can ensure that the characters being typed are not displayed on the terminal.  

#!/bin/bash
read -p "Enter name " name 
echo "Hi, $name"
read -sp "Enter password " pass
echo
echo "$name has provided the password $pass"
echo

We are making sure that the user input is not visible while it is getting entered. To achieve that we use the -s flag available with the read command to silent the echo from the user input. This allows working with the read command in a secure way. As a result bash doesn’t display what the user is typing. That input is stored in a variable passed with the read command and can be processed as per the requirements. 

The script is taking username and password from the user. The password is silent and anything entered by the user as password isn’t displayed. It is stored in the variable and that variable is printed.

Read with asterisks 

When prompted for password, we often see passwords getting replaced by asterisks (*). There is no direct way to do that in Bash. However, we can achieve the same by writing a script.

#!/bin/bash
pass=""
pass_var="Your password :"		# to take password character wise
while IFS= read -p "$pass_var" -r -s -n 1 letter
do
    if [[ $letter == $'\0' ]]		#  if enter is pressed, exit the loop
    then
        break
    fi
    
    pass="${pass}$letter"		 # store the letter in pass, use pass+="$letter" for more concise and readable.
    pass_var="*"			# in place of password the asterisk (*) will be printed
done

We are asking for the user to provide a password. In the while loop we take help of the IFS (Internal Field Separator) to split the characters. The read command with the -r flag will read the password. -s flag will ensure that the password is read silently. To display the input character by character we have supplied the -p flag to the read command. The -n option does not print the trailing newline. 

The script is prompting for the password and reading it character by character until the enter button isn’t pressed by the user. For every character that is being supplied from the prompt, the script is replacing it by the asterisk (*).

Read from a file

There have been numerous instances where the user has the password or the key present in a file. Let's first understand how to create a password file.

It is always advised to keep the password file hidden. In Linux, you can do so by creating a file beginning with a dot(.), say .passwd.txt. We will create this file by opening your favorite editor, entering the password and saving it.

To secure it even further, change the permissions on the file so that no one else can access it. To achieve that we will use the chmod tool. We can verify the permissions on this file using the ls -al command. Here’s how we do it:

echo "password123" > .passwd.txt		#Writing the content to file
chmod 600 .passwd.txt			# Giving suitable permissions
ls -al .passwd.txt				#Check permissions

Once the password file is ready, here’s an example to read the contents directly from there.

#!/bin/bash
passFile=".passwd.txt"
pass=`cat $passFile`
echo Password read from the $passFile is $pass

<Screenshot bash-read-pass-042023-03.png>

The script reads the password from the file passwd.txt using the cat command. It will store the password in the variable pass. Once the password is assigned to the variable, we can do any further processing as per the needs.

Secure Read in Bash

It is always advised to have passwords encrypted in Linux bash shell scripts. Keeping passwords as plain text puts the sensitive data at serious risk.

Encrypt the read password

If we store a password in clear, readable text, anyone with access to our system can read it. Hence, it is always a good practice to encrypt our passwords. There is a command line tool called openssl providing us with cryptography functions of OpenSSL’s crypto library from the shell.

#!/bin/bash
read -sp "Enter your password: " pass
encryptedPass=`echo $pass | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'An0terS3cr3t'`
echo
echo "Encrypted password is " $encryptedPass

The input password is encrypted using the openssl tool. Many parameters are passed with it. Let’s understand the purpose of each.

ParameterUsed for
enc -aes-256-cbcIt represents the encoding type. We are using 256 block Advanced Encryption Standard with Cipher Block Chaining(CBC)
md sha512It represents the message digest type. In our case, we employ the SHA512 cryptographic algorithm
aIt represents encoding and decoding in base64 formation. It performs encoding the operation after encryption and decoding before the decryption
pbkdf2It represents the Password-Based Key Derivation Function 2(PBKDF2) which ensures that the brute force attacks are more difficult
iterIt represents the number of computations that will be used by the PBKDF2. In our case, we have considered 1000
saltIt represents random data which ensures that the encrypted data differs every time, even for the same password
passIt represents the password or the key that will be used to encrypt the data. We have taken it as 'An0terS3cr3t'

We have supplied the password as ABCdef1@ to the script and stored it in a variable. We perform an echo on the password and pipe the output as an input to the openssl command. The openssl then, with the mentioned parameters, encrypts the password.

Decrypt the encrypted password

Just as we tried encrypting the password, we can decrypt the same. We will again use the openssl command in a similar manner.

#!/bin/bash

read -sp "Enter your password: " pass
encryptedPass=`echo $pass | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'An0terS3cr3t'`
echo
echo "Encrypted password is " $encryptedPass

decryptedPass=`echo $encryptedPass | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'An0terS3cr3t' -d`
echo
echo "Decrypted password is " $decryptedPass

The decryption of password, using openssl, works exactly in the same manner as the encryption. The data taken as input is given to the open ssl command along with the parameters. The result of this operation is assigned to a variable which holds the decrypted data.

When prompted for the password, we gave ABCdef1@. The password is then encrypted just as we did in the last case. This data, stored in a variable, is then piped as input to the openssl command. The openssl, with the described parameters, decrypts the password back to its original form. We are finally displaying the decrypted value on the screen.

Conclusion

  • Passwords as plain texts pose quite a serious and basic security flaw.
  • The read command can be used to read passwords by using its flags.
  • We have learned how to create and read hidden password files.
  • The openssl utility is a widely used tool for encryption and decryption.
SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment