在bash文件中隐藏/加密密码以阻止意外查看

Ric*_*ich 34 unix security passwords bash

对不起,如果之前有人询问,我确实检查过但找不到任何东西......

在Unix中是否有一个函数来加密解密批处理文件中的密码,以便我可以将它传递给bash文件中的其他命令?

我意识到这样做并不提供真正的安全性,如果他们正在看我的肩膀上的脚本,更多的是阻止有人意外地看到密码:)

我正在使用Red Hat 5.3.

我有一个类似于此的脚本:

serverControl.sh -u admin -p myPassword -c shutdown
Run Code Online (Sandbox Code Playgroud)

我想做这样的事情:

password = decrypt("fgsfkageaivgea", "aDecryptionKey")
serverControl.sh -u admin -p $password -c shutdown
Run Code Online (Sandbox Code Playgroud)

这不会以任何方式保护密码,但会阻止某人意外地看到我的密码.

Kal*_*son 26

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
Run Code Online (Sandbox Code Playgroud)

  • 我相信建议使用`$(echo $ FOO)`样式而不是'\`echo $ FOO \``样式. (4认同)
  • 这正是我需要的!除了......人们运行解码命令来获取明文密码是微不足道的。这可能是一个愚蠢的问题,但是有没有办法阻止用户获取密码? (2认同)

小智 10

我使用base64来克服同样的问题,即人们可以看到我的密码.

这是我做的 - 我创建了一个新的"db_auth.cfg"文件并创建了一个参数,其中一个是我的db密码.我为该文件设置了750的权限.

DB_PASSWORD=Z29vZ2xl
Run Code Online (Sandbox Code Playgroud)

在我的shell脚本中,我使用"source"命令获取文件,然后将其解码回来在我的脚本中使用.

source path_to_the_file/db_auth.cfg
DB_PASSWORD=$(eval echo ${DB_PASSWORD} | base64 --decode)
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助.

  • 如上所述,编码与加密不同.虽然您可能会对密码进行模糊处理并防止随意肩膀冲浪,但它很容易恢复:您的DB_PASSWORD是"google". (7认同)

Ale*_*ick 5

尽管这不是内置的 Unix 解决方案,但我已经使用 shell 脚本为此实现了一个解决方案,该脚本可以包含在您使用的任何 shell 脚本中。这可用于符合 POSIX 的设置。(sh, bash, ksh, zsh) 完整的描述可以在 github repo -> https://github.com/plyint/encpass.sh 中找到。此解决方案将为您的脚本自动生成一个密钥,并将密钥和您的密码(或其他机密)存储在您用户下的隐藏目录中(即 ~/.encpass)。

在您的脚本中,您只需要获取 encpass.sh,然后调用 get_secret 方法。例如:

#!/bin/sh
. encpass.sh
password=$(get_secret)
Run Code Online (Sandbox Code Playgroud)

下面粘贴的是 encpass.sh 代码的精简版(您可以在 github 上获得完整版本),以便于查看:

 #!/bin/sh
 ################################################################################
 # Copyright (c) 2020 Plyint, LLC <contact@plyint.com>. All Rights Reserved.
 # This file is licensed under the MIT License (MIT). 
 # Please see LICENSE.txt for more information.
 # 
 # DESCRIPTION: 
 # This script allows a user to encrypt a password (or any other secret) at 
 # runtime and then use it, decrypted, within a 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 bucket) that stores secrets.  This key will then be used to encrypt 
 # all secrets for that script or bucket.  encpass.sh sets up a directory 
 # (.encpass) under the user's home directory where keys and secrets will be 
 # stored.
 #
 # For further details, see README.md or run "./encpass ?" from the command line.
 #
 ################################################################################

 encpass_checks() {
    [ -n "$ENCPASS_CHECKS" ] && return

    if [ -z "$ENCPASS_HOME_DIR" ]; then
        ENCPASS_HOME_DIR="$HOME/.encpass"
    fi
    [ ! -d "$ENCPASS_HOME_DIR" ] && mkdir -m 700 "$ENCPASS_HOME_DIR"

    if [ -f "$ENCPASS_HOME_DIR/.extension" ]; then
        # Extension enabled, load it...
        ENCPASS_EXTENSION="$(cat "$ENCPASS_HOME_DIR/.extension")"
        ENCPASS_EXT_FILE="encpass-$ENCPASS_EXTENSION.sh"
        if [ -f "./extensions/$ENCPASS_EXTENSION/$ENCPASS_EXT_FILE" ]; then
            # shellcheck source=/dev/null
          . "./extensions/$ENCPASS_EXTENSION/$ENCPASS_EXT_FILE"
        elif [ ! -z "$(command -v encpass-"$ENCPASS_EXTENSION".sh)" ]; then 
            # shellcheck source=/dev/null
            . "$(command -v encpass-$ENCPASS_EXTENSION.sh)"
        else
            encpass_die "Error: Extension $ENCPASS_EXTENSION could not be found."
        fi

        # Extension specific checks, mandatory function for extensions
        encpass_"${ENCPASS_EXTENSION}"_checks
    else
        # Use default OpenSSL implementation
        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

        [ ! -d "$ENCPASS_HOME_DIR/keys" ] && mkdir -m 700 "$ENCPASS_HOME_DIR/keys"
        [ ! -d "$ENCPASS_HOME_DIR/secrets" ] && mkdir -m 700 "$ENCPASS_HOME_DIR/secrets"
        [ ! -d "$ENCPASS_HOME_DIR/exports" ] && mkdir -m 700 "$ENCPASS_HOME_DIR/exports"

    fi

   ENCPASS_CHECKS=1
 }

 # Checks if the enabled extension has implented the passed function and if so calls it
 encpass_ext_func() {
   [ ! -z "$ENCPASS_EXTENSION" ] && ENCPASS_EXT_FUNC="$(command -v "encpass_${ENCPASS_EXTENSION}_$1")" || return
    [ ! -z "$ENCPASS_EXT_FUNC" ] && shift && $ENCPASS_EXT_FUNC "$@" 
 }

 # Initializations performed when the script is included by another script
 encpass_include_init() {
    encpass_ext_func "include_init" "$@"
    [ ! -z "$ENCPASS_EXT_FUNC" ] && return

    if [ -n "$1" ] && [ -n "$2" ]; then
        ENCPASS_BUCKET=$1
        ENCPASS_SECRET_NAME=$2
    elif [ -n "$1" ]; then
        if [ -z "$ENCPASS_BUCKET" ]; then
          ENCPASS_BUCKET=$(basename "$0")
        fi
        ENCPASS_SECRET_NAME=$1
    else
        ENCPASS_BUCKET=$(basename "$0")
        ENCPASS_SECRET_NAME="password"
    fi
 }

 encpass_generate_private_key() {
    ENCPASS_KEY_DIR="$ENCPASS_HOME_DIR/keys/$ENCPASS_BUCKET"

    [ ! -d "$ENCPASS_KEY_DIR" ] && mkdir -m 700 "$ENCPASS_KEY_DIR"

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

 encpass_set_private_key_abs_name() {
    ENCPASS_PRIVATE_KEY_ABS_NAME="$ENCPASS_HOME_DIR/keys/$ENCPASS_BUCKET/private.key"
    [ ! -n "$1" ] && [ ! -f "$ENCPASS_PRIVATE_KEY_ABS_NAME" ] && encpass_generate_private_key
 }

 encpass_set_secret_abs_name() {
    ENCPASS_SECRET_ABS_NAME="$ENCPASS_HOME_DIR/secrets/$ENCPASS_BUCKET/$ENCPASS_SECRET_NAME.enc"
    [ ! -n "$1" ] && [ ! -f "$ENCPASS_SECRET_ABS_NAME" ] && set_secret
 }

 encpass_rmfifo() {
    trap - EXIT
    kill "$1" 2>/dev/null
    rm -f "$2"
 }

 encpass_mkfifo() {
    fifo="$ENCPASS_HOME_DIR/$1.$$"
    mkfifo -m 600 "$fifo" || encpass_die "Error: unable to create named pipe"
    printf '%s\n' "$fifo"
 }

 get_secret() {
    encpass_checks
    encpass_ext_func "get_secret" "$@"; [ ! -z "$ENCPASS_EXT_FUNC" ] && return

    [ "$(basename "$0")" != "encpass.sh" ] && encpass_include_init "$1" "$2"

    encpass_set_private_key_abs_name
    encpass_set_secret_abs_name
    encpass_decrypt_secret "$@"
 }

 set_secret() {
    encpass_checks

    encpass_ext_func "set_secret" "$@"; [ ! -z "$ENCPASS_EXT_FUNC" ] && return

    if [ "$1" != "reuse" ] || { [ -z "$ENCPASS_SECRET_INPUT" ] && [ -z "$ENCPASS_CSECRET_INPUT" ]; }; then
        echo "Enter $ENCPASS_SECRET_NAME:" >&2
        stty -echo
        read -r ENCPASS_SECRET_INPUT
        stty echo
        echo "Confirm $ENCPASS_SECRET_NAME:" >&2
        stty -echo
        read -r ENCPASS_CSECRET_INPUT
        stty echo

        # Use named pipe to securely pass secret to openssl
        fifo="$(encpass_mkfifo set_secret_fifo)"
    fi

    if [ "$ENCPASS_SECRET_INPUT" = "$ENCPASS_CSECRET_INPUT" ]; then
        encpass_set_private_key_abs_name
        ENCPASS_SECRET_DIR="$ENCPASS_HOME_DIR/secrets/$ENCPASS_BUCKET"

        [ ! -d "$ENCPASS_SECRET_DIR" ] && mkdir -m 700 "$ENCPASS_SECRET_DIR"

        # Generate IV and create secret file
        printf "%s" "$(openssl rand -hex 16)" > "$ENCPASS_SECRET_DIR/$ENCPASS_SECRET_NAME.enc"
        ENCPASS_OPENSSL_IV="$(cat "$ENCPASS_SECRET_DIR/$ENCPASS_SECRET_NAME.enc")"

        echo "$ENCPASS_SECRET_INPUT" > "$fifo" &
        # Allow expansion now so PID is set
        # shellcheck disable=SC2064
        trap "encpass_rmfifo $! $fifo" EXIT HUP TERM INT TSTP

        # Append encrypted secret to IV in the secret file
        openssl enc -aes-256-cbc -e -a -iv "$ENCPASS_OPENSSL_IV" \
            -K "$(cat "$ENCPASS_HOME_DIR/keys/$ENCPASS_BUCKET/private.key")" \
            -in "$fifo" 1>> "$ENCPASS_SECRET_DIR/$ENCPASS_SECRET_NAME.enc"
    else
        encpass_die "Error: secrets do not match.  Please try again."
    fi
 }

 encpass_decrypt_secret() {
    encpass_ext_func "decrypt_secret" "$@"; [ ! -z "$ENCPASS_EXT_FUNC" ] && return

    if [ -f "$ENCPASS_PRIVATE_KEY_ABS_NAME" ]; then
        ENCPASS_DECRYPT_RESULT="$(dd if="$ENCPASS_SECRET_ABS_NAME" ibs=1 skip=32 2> /dev/null | openssl enc -aes-256-cbc \
            -d -a -iv "$(head -c 32 "$ENCPASS_SECRET_ABS_NAME")" -K "$(cat "$ENCPASS_PRIVATE_KEY_ABS_NAME")" 2> /dev/null)"
        if [ ! -z "$ENCPASS_DECRYPT_RESULT" ]; then
            echo "$ENCPASS_DECRYPT_RESULT"
        else
            # If a failed unlock command occurred and the user tries to show the secret
            # Present either a locked or failed decrypt error.
            if [ -f "$ENCPASS_HOME_DIR/keys/$ENCPASS_BUCKET/private.lock" ]; then 
            echo "**Locked**"
            else
                # The locked file wasn't present as expected.  Let's display a failure
            echo "Error: Failed to decrypt"
            fi
        fi
    elif [ -f "$ENCPASS_HOME_DIR/keys/$ENCPASS_BUCKET/private.lock" ]; then
        echo "**Locked**"
    else
        echo "Error: Unable to decrypt. The key file \"$ENCPASS_PRIVATE_KEY_ABS_NAME\" is not present."
    fi
 }

 encpass_die() {
   echo "$@" >&2
   exit 1
 }
 #LITE
Run Code Online (Sandbox Code Playgroud)