1'den fazla program için parola geçirmenin güvenli yolu


21

Bir bashsenaryo yazıyorum ve kullanıcıdan şifresini sorup geçmesi gerekiyor openssl. İken opensslşifreyi kendisi okuyabilir, ben programın iki ishal için ihtiyaç ve iki kez kullanıcıyı sormak istemiyorum. İşte senaryo:

cp file{,.old}
read -sp 'Enter password. ' PASS; echo
export PASS

# decode | edit | encode
openssl enc -d -aes-256-cbc -k "$PASS" -in file.old | \
  sed ... | openssl enc -e -aes-256-cbc -k "$PASS" -out file

unset PASS

Parola komut satırına bakarak kolayca elde edilebildiğinden bu güvenli değildir; psörneğin birisi bunu kullanarak okuyabilir .

opensslBen yerine, böylece bir ortam değişkeni bir şifreyi okuyabilir -k "$PASS"ile -pass env:PASS, ama yine de güvenli değil; herhangi bir işlemin ortam değişkenleri serbestçe okunabilir (yine psyapabilir).

Peki, şifreyi iki opensslörneğe nasıl güvenli bir şekilde aktarabilirim ?


GnuPG ve PinEntry kombinasyonu burada kullanılabilir gnupg.org/related_software/pinentry/index.en.html
Nikhil Mulley

"herhangi bir işlemin ortam değişkenleri serbestçe okunabilir" - bu tamamen doğru değildir. psbir işlemin ortamını okur /proc/<pid>/environ, ancak bu dosyanın 0600izinleri vardır, bu nedenle yalnızca kök ve işlemi çalıştıran kullanıcı işlemin ortamını okuyabilir. Bunun oldukça güvenli olduğunu söyleyebilirim.
Martin von Wittich

Yanıtlar:


16

Şifreyi girişten ayrı bir dosya tanımlayıcıya aktarın (iki kez, bir kez şifreleme için ve bir kez de şifre çözme için). PASSÇevreye ihracat yapmayın .

read -sp 'Enter password. ' PASS
printf '%s\n' "$PASS" |
openssl enc -d -aes-256-cbc -kfile /dev/stdin -in file.old |
sed ... | {
  printf '%s\n' "$PASS" |
  openssl enc -e -aes-256-cbc -kfile /dev/stdin -in /dev/fd/3 -out file;
} 3<&0

Sisteminizde yoksa /dev/fd, -passargümanıopenssl açık bir dosya tanımlayıcıdan parolayı okumayı söylemek için kullanabilirsiniz .

printf '%s\n' "$PASS" | {
  printf '%s\n' "$PASS" |
  openssl enc -d -aes-256-cbc -pass fd:0 -in file.old |
  tr a-z A-Z | tee /dev/tty | {
  openssl enc -e -aes-256-cbc -pass fd:3 -out file; }
} 3<&0

Ben anladığımız gibi başka Cevabınız içinde, bashsürümü ile env:PASSçok güvenlidir.

printf '%s\n' "$PASS"güvenli değil. Birisi komut satırını psörneğin okuyabilir .

6
@ user14284 Hayır ve hayır. env:PASSgüvenli değildir, çünkü şifre opensslişlemin ortamında görünecektir (işlemin ortamında görünmez bash, ancak bu yeterli değildir). Kullanılması printfo yerleşik bir bash çünkü güvenlidir.
Gilles 'SO- kötü olmayı bırak'

echo yerleşik bir bash, bu yüzden basit bir echo komutu güvenli olmaz mı? echo $PASS | openssl .... PS listesinde görünmez. Geçebileceğiniz tek yer bash işlem belleğinde olacaktır. Bence ?
gaoithe

1
@gaoithe Evet, echoaynı nedenden dolayı printfgüvenli olur (ve printfyerleşik olmadığı bir kabukta güvenli olmaz). Kullanmamın printfve kullanmamanın nedeni echo, echoters eğik çizgileri (bash seçeneklerine bağlı olarak) manevra edebilmesidir.
Gilles 'SO- kötü olmayı bırak

8

Bash kullanarak printf '%s\n' "$PASS", burada adı verilen bir dizeyi Bash yerleşik execkomutunu kullanarak dosya tanımlayıcılarıyla ilişkilendirmeksizin kullanılabilir .

Daha fazla bilgi için, bkz . Komut satırı parametrelerinin kabuk komut dosyası parolası güvenliği .

(

# sample code to edit password-protected file with openssl
# user should have to enter password only once
# password should not become visible using the ps command

echo hello > tmp.file

#env -i bash --norc   # clean up environment
set +o history
unset PASS || exit 1

read -sp 'Enter password. ' PASS; echo

# encrypt file and protect it by given password
exec 3<<<"$PASS"
openssl enc -e -aes-256-cbc -pass fd:3  -in tmp.file -out file

cp file{,.old}

# decode | edit | encode
exec 3<<<"$PASS" 4<<<"$PASS"
openssl enc -d -aes-256-cbc -pass fd:3 -in file.old | 
   sed 's/l/L/g' | 
   openssl enc -e -aes-256-cbc -pass fd:4 -out file

exec 3<<<"$PASS"
openssl enc -d -aes-256-cbc -pass fd:3 -in file

rm -P tmp.file file.old
unset PASS

)

1

Maalesef, önceki cevabım openssl enc dokümanlarından değil openssl adamından geliyordu.

Bu çözüm bir boru hattı değil, ama bu çözüm şifrenin ps için görünür olmasını önlediğine inanıyorum.

Burada bir belge kullanarak, sadece openssl parola metnini görür.
Ara dosyayı kaldıracağınızdan emin olduğunuzda hiçbir iz kalmaz. Belki birileri bunu bir boru hattında yapmaya ve ara dosyayı ortadan kaldırmaya yardımcı olabilir?

# cp file{,.old}  don't need this anymore since intermediate becomes same
read -sp 'Enter password. ' PASS; echo
#no need to export, env's are readable, as mentioned

# decode into intermediate file
openssl <<HERE 2>&1 >/dev/null
enc -d -aes-256-cbc -k "$PASS" -in file -out intermediate
HERE

# edit intermediate

# encode intermediate back into file
openssl <<HERE 2>&1 >/dev/null
enc -e -aes-256-cbc -k "$PASS" -in intermediate -out file 
HERE
unset PASS
rm -f intermediate

Anahtarın nasıl kullanılacağını açıklarsa bu daha iyi bir cevap olacaktır. Yanlış değil ( enckomutun -knen azından geçerli sürümlerde anahtarı olmaması hariç -pass), ancak çok bilgilendirici değil. (Downvote benim değil.)
Gilles 'SO- kötü olmayı bırak'

Teşekkürler @Gilles, dokümanlara baktı ve gaf, farklı bir yaklaşımla güncellenmiş cevabımı gördüm.
bsd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.