web-dev-qa-db-fra.com

Masquer / crypter le mot de passe dans le fichier bash pour arrêter de le voir accidentellement

Désolé si cela a déjà été demandé, j'ai vérifié mais je n'ai rien trouvé ...

Existe-t-il une fonction sous Unix pour crypter et décrypter un mot de passe dans un fichier batch afin que je puisse le diriger vers d'autres commandes dans un fichier bash?

Je me rends compte que cela n'offre aucune sécurité réelle, c'est plus pour empêcher quelqu'un de voir accidentellement le mot de passe s'il regarde le script par-dessus mon épaule :)

Je cours sur Red Hat 5.3.

J'ai un script qui fait quelque chose de similaire à ceci:

serverControl.sh -u admin -p myPassword -c shutdown

et je voudrais faire quelque chose comme ça:

password = decrypt("fgsfkageaivgea", "aDecryptionKey")
serverControl.sh -u admin -p $password -c shutdown

Cela ne protège en aucun cas le mot de passe, mais empêche quelqu'un de le voir accidentellement par-dessus mon épaule.

33
Rich

OpenSSL fournit une commande passwd qui peut crypter mais ne décrypte pas car elle ne fait que des hachages. Vous pouvez également télécharger quelque chose comme aesutil afin que vous puissiez utiliser une routine de chiffrement symétrique capable et bien connue.

Par exemple:

#!/bin/sh    
# using aesutil
SALT=$(mkrand 15) # mkrand generates a 15-character random passwd
MYENCPASS="i/b9pkcpQAPy7BzH2JlqHVoJc2mNTBM=" # echo "passwd" | aes -e -b -B -p $SALT 
MYPASS=$(echo "$MYENCPASS" | aes -d -b -p $SALT)

# and usage
serverControl.sh -u admin -p $MYPASS -c shutdown
26
Kaleb Pederson

J'ai utilisé base64 pour surmonter le même problème, c'est-à-dire que les gens peuvent voir mon mot de passe par-dessus mon épaule.

Voici ce que j'ai fait - j'ai créé un nouveau fichier "db_auth.cfg" et créé des paramètres dont l'un est mon mot de passe db. J'ai défini l'autorisation sur 750 pour le fichier.

DB_PASSWORD=Z29vZ2xl

Dans mon script Shell, j'ai utilisé la commande "source" pour obtenir le fichier, puis le décoder pour l'utiliser dans mon script.

source path_to_the_file/db_auth.cfg
DB_PASSWORD=$(eval echo ${DB_PASSWORD} | base64 --decode)

J'espère que ça aide.

10
White_Nazgul

Bien que ce ne soit pas une solution Unix intégrée, j'ai implémenté une solution pour cela en utilisant un script Shell qui peut être inclus dans le script Shell que vous utilisez. Ce "devrait" être utilisable sur les configurations compatibles POSIX. La description complète est disponible dans le dépôt github -> https://github.com/ahnick/encpass.sh . Cette solution générera automatiquement une clé pour votre script et stockera la clé et votre mot de passe (ou d'autres secrets) dans un répertoire caché sous votre utilisateur (c'est-à-dire ~/.encpass).

Dans votre script, il vous suffit de source encpass.sh, puis appelez la méthode get_secret. Par exemple:

#!/bin/sh
. encpass.sh
password=$(get_secret)

Coller le code pour encpass.sh pour une meilleure visibilité:

#!/bin/sh
################################################################################
# Filename: encpass.sh
# Description: This script allows a user to encrypt a password (or any other
#              secret) at runtime and then use it, decrypted, within another
#              script. This prevents shoulder surfing passwords and avoids
#              storing the password in plain text, which could inadvertently
#              be sent to or discovered by an individual at a later date.
#
#              This script generates an AES 256 bit symmetric key for each
#              script (or user-defined label) that stores secrets.  This key
#              will then be used to encrypt all secrets for that script or
#              label.  encpass.sh sets up a directory (.encpass) under the
#              user's home directory where keys and secrets will be stored.
#
#              Subsequent calls to retrieve a secret will not Prompt for a
#              secret to be entered as the file with the encrypted value
#              already exists.
#
# Author: Xan Nick
#
# Usage: . ./encpass.sh
#        ...
#        $password=$(get_secret)
################################################################################

checks() {
if [ -n "$ENCPASS_CHECKS" ]; then
return
fi

if [ ! -x "$(command -v openssl)" ]; then
echo "Error: OpenSSL is not installed or not accessible in the current path." \
"Please install it and try again." >&2
exit 1
fi

ENCPASS_HOME_DIR=$(get_abs_filename ~)/.encpass

if [ ! -d $ENCPASS_HOME_DIR ]; then
mkdir -m 700 $ENCPASS_HOME_DIR
mkdir -m 700 $ENCPASS_HOME_DIR/keys
mkdir -m 700 $ENCPASS_HOME_DIR/secrets
fi

if [ ! -z $1 ] && [ ! -z $2 ]; then
LABEL=$1
SECRET_NAME=$2
Elif [ ! -z $1 ]; then
LABEL=$(basename $0)
SECRET_NAME=$1
else
LABEL=$(basename $0)
SECRET_NAME="password"
fi

ENCPASS_CHECKS=1
}

generate_private_key() {
KEY_DIR="$ENCPASS_HOME_DIR/keys/$LABEL"

if [ ! -d $KEY_DIR ]; then
mkdir -m 700 $KEY_DIR
fi

if [ ! -f $KEY_DIR/private.key ]; then
(umask 0377 && printf "%s" "$(openssl Rand -hex 32)" > $KEY_DIR/private.key)
fi
}

get_private_key_abs_name() {
PRIVATE_KEY_ABS_NAME="$ENCPASS_HOME_DIR/keys/$LABEL/private.key"

if [ ! -f "$PRIVATE_KEY_ABS_NAME" ]; then
generate_private_key
fi
}

get_secret_abs_name() {
SECRET_ABS_NAME="$ENCPASS_HOME_DIR/secrets/$LABEL/$SECRET_NAME.enc"

if [ ! -f "$SECRET_ABS_NAME" ]; then
set_secret $1 $2
fi
}

get_secret() {
checks $1 $2
get_private_key_abs_name
get_secret_abs_name $1 $2

dd if=$SECRET_ABS_NAME ibs=1 skip=32 2> /dev/null | openssl enc -aes-256-cbc \
-d -a -iv $(head -c 32 $SECRET_ABS_NAME) -K $(cat $PRIVATE_KEY_ABS_NAME)
}

set_secret() {
checks $1 $2
get_private_key_abs_name
SECRET_DIR="$ENCPASS_HOME_DIR/secrets/$LABEL"

if [ ! -d $SECRET_DIR ]; then
mkdir -m 700 $SECRET_DIR
fi

echo "Enter $SECRET_NAME:" >&2
stty -echo
read -r SECRET
stty echo
echo "Confirm $SECRET_NAME:" >&2
stty -echo
read -r CSECRET
stty echo
if [ "$SECRET" = "$CSECRET" ]; then
printf "%s" "$(openssl Rand -hex 16)" > \
$SECRET_DIR/$SECRET_NAME.enc

echo "$SECRET" | openssl enc -aes-256-cbc -e -a -iv \
$(cat $SECRET_DIR/$SECRET_NAME.enc) -K \
$(cat $ENCPASS_HOME_DIR/keys/$LABEL/private.key) 1>> \
$SECRET_DIR/$SECRET_NAME.enc
else
echo "Error: secrets do not match.  Please try again." >&2
exit 1
fi
}

get_abs_filename() {
# $1 : relative filename
filename=$1
parentdir=$(dirname "${filename}")

if [ -d "${filename}" ]; then
echo "$(cd "${filename}" && pwd)"
Elif [ -d "${parentdir}" ]; then
echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
fi
}
3
Alexander Nick

Vous devriez pouvoir utiliser crypt, mcrypt ou gpg pour répondre à vos besoins. Ils prennent tous en charge un certain nombre d'algorithmes. crypt est cependant un peu dépassé.

Plus d'informations:

2
Lèse majesté

Une autre solution, sans égard à la sécurité (je pense aussi qu'il vaut mieux conserver les informations d'identification dans un autre fichier ou dans une base de données) est de crypter le mot de passe avec gpg et de l'insérer dans le script.

J'utilise une paire de clés gpg sans mot de passe que je garde dans une clé USB. (Remarque: lorsque vous exportez cette paire de clés, n'utilisez pas --armor, exportez-les au format binaire).

Cryptez d'abord votre mot de passe:

EDIT : Mettez un espace avant cette commande, donc il n'est pas enregistré par l'historique bash.

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient [email protected] --encrypt

Ce sera imprimé le mot de passe crypté gpg dans la sortie standard. Copiez l'intégralité du message et ajoutez-le au script:

password=$(gpg --batch --quiet --no-default-keyring --secret-keyring /media/usb/key.priv --decrypt <<EOF 
-----BEGIN PGP MESSAGE-----

hQEMA0CjbyauRLJ8AQgAkZT5gK8TrdH6cZEy+Ufl0PObGZJ1YEbshacZb88RlRB9
h2z+s/Bso5HQxNd5tzkwulvhmoGu6K6hpMXM3mbYl07jHF4qr+oWijDkdjHBVcn5
0mkpYO1riUf0HXIYnvCZq/4k/ajGZRm8EdDy2JIWuwiidQ18irp07UUNO+AB9mq8
5VXUjUN3tLTexg4sLZDKFYGRi4fyVrYKGsi0i5AEHKwn5SmTb3f1pa5yXbv68eYE
lCVfy51rBbG87UTycZ3gFQjf1UkNVbp0WV+RPEM9JR7dgR+9I8bKCuKLFLnGaqvc
beA3A6eMpzXQqsAg6GGo3PW6fMHqe1ZCvidi6e4a/dJDAbHq0XWp93qcwygnWeQW
Ozr1hr5mCa+QkUSymxiUrRncRhyqSP0ok5j4rjwSJu9vmHTEUapiyQMQaEIF2e2S
/NIWGg==
=uriR
-----END PGP MESSAGE-----
EOF)

De cette façon, uniquement si l'USB est monté dans le système, le mot de passe peut être déchiffré. Bien sûr, vous pouvez également importer les clés dans le système (moins sécurisées, ou pas de sécurité du tout) ou vous pouvez protéger la clé privée avec un mot de passe (donc elle ne peut pas être automatisée).

1
Juanu