openssl: Passwörter als Parameter vermeiden

Passwörter als Kommandozeilenparameter sind immer ein potentielles Sicherheitsleck, da sie in der Ausgabe von ps, top, htop, etc. für alle Nutzer eines Systems zu sehen sind.

openssl erlaubt die Angabe eines Dateideskriptors als Passwortquelle, in Kombination mit einem FIFO und bash-I/O-Umleitung können wir programmatisch das Erscheinen des Passwortes in den Systeminformationen vermeiden.

  • Einen FIFO erzeugen
    mkfifo fifoname
  • Den Dateideskriptor 9 auf den FIFO umleiten
    exec 9<>fifoname
  • Das Passwort in den FIFO schreiben
    echo $pass >&9
  • openssl aus dem Dateideskriptor 9 das Passwort lesen lassen mit dem Parameter
    -pass "fd:9"
  • Aufräumen, d.h. den Dateideskriptor 9 wieder freigeben, den FIFO entfernen
    exec 9&-
    rm $PWD/fifoname
         

Zusammenfassen können wir das in zwei Funktionen zum Ver- und Entschlüsseln von übergebenen Daten:

openssl_encrypt() {
    local pass="$1"
    local text="$2"
    local fifo="$(rand_str 10 true)"
    /usr/bin/mkfifo $PWD/$fifo
    exec 9<>$PWD/$fifo
    echo $pass >&9
    echo "$text" | openssl bf -e -a -salt -pass "fd:9"
    status=$?
    exec 9<&-
    exec 9>&-
    rm $PWD/$fifo
    return $status
}
openssl_decrypt() {
    local pass="$1"
    local text="$2"
    local fifo="$(rand_str 10 true)"
    /usr/bin/mkfifo $PWD/$fifo
    exec 9<>"$PWD/$fifo"
    echo $pass >&9
    echo "$text" | openssl bf -d -a -salt -pass "fd:9"
    status=$?
    exec 9<&-
    exec 9>&-
    rm $PWD/$fifo
    return $status
}

Die rand_str Funktion stammt aus der Shell-Bibliothek von Chris F.A. Johnson:

rand_str() {
    local length=$1
    local ascii=$2
    local result=""
    [ -z "$ascii" ] && ascii=true
    local range=94
    local offset=32
    if [ "$ascii" == "true" ]; then
        range=61
        offset=65
    fi
    for i in $(seq 1 1 $length); do        
        result+="$(printf "%03d" "$(dec2oct $(($RANDOM % $range + $offset)))")"
    done
    echo -e "$result"
}

dec2oct() {
    local quotient=$1
    local remainder=
    local octal=
    while [ $quotient -ne 0 ]
    do
        remainder=$(( $quotient % 8 ))
        octal="$remainder$octal"
        quotient=$(( $quotient / 8 ))
    done

    echo $octal
}