Скрыть / зашифровать пароль в файле bash, чтобы случайно не увидеть его - PullRequest
33 голосов
/ 23 июля 2010

Извините, если раньше об этом спрашивали, я проверил, но ничего не смог найти ...

Есть ли в Unix функция для шифрования и дешифрования пароля в командном файле, чтобы я мог передать его другим командам в файле bash?

Я понимаю, что выполнение этого не обеспечивает реальной безопасности, это больше, чтобы остановить кого-то случайно увидев пароль, если они смотрят на сценарий через мое плечо:)

Я работаю на Red Hat 5.3.

У меня есть скрипт, который делает что-то похожее на это:

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

и я хотел бы сделать что-то вроде этого:

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

Это никак не защищает пароль, но мешает кому-то случайно увидеть его через плечо.

Ответы [ 8 ]

26 голосов
/ 23 июля 2010

OpenSSL предоставляет команду passwd , которая может шифровать, но не дешифрует, поскольку выполняет только хеширование. Вы также можете загрузить что-то вроде aesutil , чтобы использовать эффективную и хорошо известную процедуру симметричного шифрования.

Например:

#!/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
9 голосов
/ 23 февраля 2015

Я использовал base64 для преодоления той же проблемы, то есть люди могут видеть мой пароль через плечо.

Вот что я сделал - Я создал новый файл "db_auth.cfg" и создал параметры, один из которых - мой пароль базы данных. Я установил разрешение 750 для файла.

DB_PASSWORD=Z29vZ2xl

В моем сценарии оболочки я использовал команду «source», чтобы получить файл, а затем декодировать его обратно для использования в моем сценарии.

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

Надеюсь, это поможет.

3 голосов
/ 22 февраля 2018

Хотя это не встроенное решение Unix, я реализовал решение для этого с помощью сценария оболочки, который может быть включен в любой используемый сценарий оболочки.Это «должно» использоваться на POSIX-совместимых установках.Полное описание доступно в репозитории github -> https://github.com/ahnick/encpass.sh.. Это решение автоматически сгенерирует ключ для вашего скрипта и сохранит ключ и ваш пароль (или другие секреты) в скрытом каталоге под вашим пользователем (т.е./.encpass).

В вашем скрипте вам просто нужно набрать encpass.sh и затем вызвать метод get_secret.Например:

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

Вставка кода для encpass.sh для удобства просмотра:

#!/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
}
2 голосов
/ 23 июля 2010

Вы должны иметь возможность использовать crypt, mcrypt или gpg для удовлетворения своих потребностей. Все они поддерживают ряд алгоритмов. crypt немного устарел.

Дополнительная информация:

1 голос
/ 16 декабря 2016

Другое решение, не учитывая безопасность (я также считаю, что учетные данные лучше хранить в другом файле или в базе данных), заключается в шифровании пароля с помощью gpg и вставке его в сценарий.

Я использую пару ключей gpg без пароля, которые я храню в USB.(Примечание. При экспорте этой пары ключей не используйте --armor, экспортируйте их в двоичном формате).

Сначала зашифруйте свой пароль:

РЕДАКТИРОВАТЬ : Поставьте пробел перед этой командой, чтобы она не записывалась в истории bash.

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient someone@mail.com --encrypt

Это будет распечатывать зашифрованный пароль gpg в стандартном выводе.Скопируйте сообщение целиком и добавьте его в сценарий:

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)

Таким образом, только если usb подключен к системе, пароль может быть расшифрован.Конечно, вы также можете импортировать ключи в систему (менее безопасный или вообще не защищенный) или вы можете защитить личный ключ паролем (поэтому его нельзя автоматизировать).

0 голосов
/ 21 мая 2016

Существует более удобный способ хранения паролей в сценарии, но вам придется зашифровать и скрыть сценарий, чтобы его нельзя было прочитать. Чтобы успешно зашифровать и скрыть сценарий оболочки и фактически сделать этот сценарий исполняемым, попробуйте скопировать и вставить его здесь:

http://www.kinglazy.com/shell-script-encryption-kinglazy-shieldx.htm

На приведенной выше странице все, что вам нужно сделать, это отправить свой сценарий и дать ему правильное имя, а затем нажать кнопку загрузки. Zip-файл будет создан для вас. Щелкните правой кнопкой мыши ссылку для скачивания и скопируйте предоставленный вами URL. Затем перейдите в окно UNIX и выполните следующие действия.

Установка:

1. wget link-to-the-zip-file
2. unzip the-newly-downloaded-zip-file
3. cd /tmp/KingLazySHIELD
4. ./install.sh /var/tmp/KINGLAZY/SHIELDX-(your-script-name) /home/(your-username) -force

Что сделает для вас приведенная выше команда установки:

  1. Установите зашифрованную версию вашего скрипта в каталог /var/tmp/KINGLAZY/SHIELDX-(your-script-name).
  2. Он поместит ссылку на этот зашифрованный скрипт в любой каталог, который вы указали при замене / home / (ваше имя пользователя) - таким образом, он позволит вам легко получить доступ к скрипту без необходимости вводить абсолютный путь. 1020 *
  3. Гарантирует, что НИКТО не сможет изменить сценарий. Любые попытки изменить зашифрованный сценарий приведут к его неработоспособности ... до тех пор, пока эти попытки не будут остановлены или удалены. Он даже может быть настроен на , чтобы уведомлять вас всякий раз, когда кто-то пытается что-то сделать со сценарием, кроме как запустить его ... т.е. попытки взлома или модификации.
  4. Гарантирует, что абсолютно НИКТО не сможет сделать его копии. Никто не может скопировать ваш скрипт в укромное место и попытаться обойти его, чтобы посмотреть, как он работает. Все копии скрипта должны быть ссылками на исходное местоположение, указанное вами при установке (шаг 4).

Примечание:

Это не работает для интерактивных сценариев, которые запрашивают и ждут от пользователя ответа. Значения, ожидаемые от пользователя, должны быть жестко запрограммированы в сценарии. Шифрование гарантирует, что никто не сможет увидеть эти значения, поэтому вам не нужно об этом беспокоиться.

ОТНОШЕНИЕ:

Решение, представленное в этом посте, отвечает вашей проблеме в том смысле, что оно шифрует фактический скрипт, содержащий пароль, который вы хотели зашифровать. Вы можете оставить пароль как есть (не зашифрованным), но сценарий, в котором находится пароль, настолько глубоко запутан и зашифрован, что вы можете быть уверены, что никто не сможет его увидеть. И если будут предприняты попытки попытаться проникнуть в скрипт, вы получите уведомления о них по электронной почте.

0 голосов
/ 05 января 2016

Следующая строка в приведенном выше коде не работает

DB_PASSWORD=$(eval echo ${DB_PASSWORD} | base64 --decode)

Правильная строка:

DB_PASSWORD=`echo $PASSWORD|base64 -d`

И сохраните пароль в другом файле как ПАРОЛЬ.

0 голосов
/ 23 июля 2010
  • отступ от края экрана (при условии, что вы не используете перенос строк и у вас есть постоянный редактор ширины)

или

  • сохраните его в отдельном файле и прочитайте в.
...