Password Encryption in Shell Scripts
Ed Schaefer
As a system administrator, have you ever desired a quick method for password protecting a shell script or other program? Although some UNIX variants provide the crypt utility, it's not typically part of a normal operating system release because of export restrictions. This article presents a utility named coffin, which, when included in a shell script, verifies a user-entered password before allowing program execution to continue.
Coffin works like this: prompt the user for a password; execute coffin with the password as an argument. Sample the exit value of coffin and, if it is zero, continue executing or else terminate. Coffin, written in C, is a symmetrical key, CRC-checked, xor-based, ascii-encoded, encryption algorithm. Before investigating coffin further, let's define some terms as they will be used in this article:
Plaintext - The message being hidden. (The message is a password in our case.)
Ciphertext - The message in encrypted form.
Encryption - The process or algorithm used to hide or change a message to ciphertext.
Decryption - The process or algorithm used to turn ciphertext back to plaintext.
Symmetrical key - The same mathematical key, a string of ascii characters, is used for encrypting as well as decrypting.
ascii-encoded - The ciphertext stored in the encrypt.fil is guaranteed to be ascii and not binary.
Using Coffin Before coffin can be used in a shell script, you must store the ciphertext password in the file encrypt.fil. The command to do so is:
coffin -e {password} {key}
where the encryption flag is -e. The password to be encrypted and the symetrical key are the arguments password and key, respectively.
Here is the pseudo-code:
- Pass the password to encrypt and the symetrical key as arguments.
- Obtain the CRC of the plaintext password.
- Write the key to the file named key.fil.
- Append the last five characters of the CRC to the end of the plaintext password.
- Encode the plaintext to ciphertext with the xor function.
- Change the ciphertext to ascii.
- Write the resulting ciphertext to the file named encrypt.fil.
Listing 1, new.ss, is an example of Coffin in action. Prompt the user to enter a password. Execute coffin with the -d switch, passing the password. If the exit code equals zero, the shell script is run. If not, access is denied, and the shell script terminates.
Listing 2, snew.ss, is a more professional sample script. This script replaces the shell "read" statement used in Listing 1 with a "C" program, get_char, which not only prompts the user to enter a password, but also turns off echoing characters to the screen.
Listing 3 is the source to get_char. get_char is simply a "while" loop that calls a non-echoing function, ret_char, which returns one character until the carriage return is pressed or until a defined length is reached. The ret_char function source code is not included here, but was extensively covered in the April, 1997 issue of Sys Admin article, "Returning a Single Character in a UNIX Shell Script".
To utilize coffin decrypt, the shell script executes:
coffin -d {$password}
with the values for the password and key being extracted from the environment within the script.
The password is decrypted in reverse order from encrypt:
- Pass the password as an argument to decrypt.
- Read the file named encrypt.fil to obtain the ciphertext password.
- Read the file named key.fil to obtain the key.
- Change the ciphertext password to ascii.
- Decode the ciphertext password to plaintext (including the original CRC) with the xor function.
- If the original CRC doesn't agree with the CRC of the plaintext password, send an error to the root user.
- Set the exit code to zero if the password to check is the same as the plaintext password, or to one if it is not.
Inside Coffin The heart of coffin is the XOR mathematical function used to encrypt and decrypt the password. In his book, Applied Cryptography, Bruce Schneier describes the XOR algorithm as an "embarrassment". The amount of time needed or work factor for a trained cryptographer to break the algorithm is minimal.
Although the simplicity of the XOR algorithm allows its use in this article, the most obvious enhancement to coffin would be an improved cryptographic algorithm. Most cryptographic algorithms are patented so their use is restricted. Also, the U.S. Government tightly controls the use and export of all things cryptographic. Other commercial algorithms such as DES, A5, SEAL, etc. could be used to replace XOR, with the appropriate license.
The Cyclic Redundancy Check (CRC) warns the root user if someone has tampered with the encrypt.fil. When the password was encrypted, the CRC of the password was stored in the last five characters of the ciphertext. Strip off these last five characters, because they are the original CRC.
When decrypting ciphertext, coffin strips off the last five characters of the plaintext and chnges them to an integer. It then computes the CRC of the plaintext minus the last five characters. If the computed CRC does not equal the orginal CRC, coffin alerts the root user with the crc_error function call and exits with an error code. Note, that except for the crc_error and getuid functions, coffin may be used with any non-UNIX operating system, which is why the UNIX_SW is used. For more information, see the sidebar on CRC.
Originally, coffin was designed to read and write to a window's INI file, which required the ciphertext to be in ASCII. The functions used to convert to and from ASCII are modified versions of the UNIX utilities uuencode and uudecode.
Coffin Security Without care, the coffin utility is susceptible to a possible Trojan horse. File permissions for coffin include the userid being set, which allows the encrypt.fil to be read only:
-r-s--s--- 1 tmpusr tmpusr 35124 Apr 23 19:26 coffin
-r-------- 1 tmpusr tmpusr 25 Apr 20 20:51 encrypt.fil
-r-------- 1 tmpusr tmpusr 8 Apr 20 20:51 key.fil
-rwx--x--- 1 tmpusr tmpusr 31716 Apr 23 19:39 get_char
-r-xr-x--- 1 tmpusr tmpusr 189 Apr 20 21:00 new.ss
-r-xr-x--- 1 tmpusr tmpusr 205 Apr 23 19:34 snew.ss
Coffin only allows the encryption option to be executed by the root user.
References Applied Cryptography: Protocols, algorithms, and source code in C by Bruce Schneier. John Wiley & Sons, 1996.
About the Author
Ed Schaefer has been involved with UNIX since the mid 1980s. Presently, He is a senior programmer/analyst for Intel's Factory Information and Control System (iFICS) Group in Hillsboro, Oregon. His viewpoints on crytography or any other subject in no way reflects Intel's position. He can be reached at: olded@ix.netcom.com.
|