bash에서> 1 프로그램의 암호를 안전하게 전달하는 방법


21

bash스크립트를 작성 중이며 사용자에게 비밀번호를 요청하고에 전달해야합니다 openssl. openssl암호 자체를 읽을 수는 있지만 프로그램을 두 번 실행해야하며 사용자에게 두 번 묻고 싶지 않습니다. 스크립트는 다음과 같습니다.

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

명령 행을 보면 암호를 쉽게 사용할 수 있으므로 안전하지 않습니다. ps예를 들어 누군가가 그것을 사용하여 읽을 수 있습니다 .

openssl내가 대체 할 수 있도록 환경 변수에서 암호를 읽을 수 -k "$PASS"와 함께 -pass env:PASS,하지만 여전히 안전하지; 모든 프로세스의 환경 변수를 자유롭게 읽을 수 있습니다 (다시 ps할 수 있음).

그렇다면 어떻게 두 openssl인스턴스에 암호를 안전하게 전달할 수 있습니까?


GnuPG와 PinEntry의 조합은 여기에서 사용할 수 있습니다. gnupg.org/related_software/pinentry/index.en.html
Nikhil Mulley

"모든 프로세스의 환경 변수를 자유롭게 읽을 수 있습니다"-이것은 완전히 정확하지 않습니다. ps에서 프로세스 환경을 읽지 만이 /proc/<pid>/environ파일에는 0600권한이 있으므로 프로세스를 실행하는 루트 및 사용자 만 프로세스 환경을 읽을 수 있습니다. 나는 그것이 꽤 안전하다고 말하고 싶습니다.
Martin von Wittich

답변:


16

입력과는 별도의 파일 설명자에 암호를 전달하십시오 (두 번, 암호화 및 암호 해제를 위해 한 번). PASS환경으로 내 보내지 마십시오 .

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

시스템에가 없으면 인수/dev/fd사용하여 열린 파일 설명자에서 암호를 읽 도록 지시 할 수 있습니다 .-passopenssl

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

내가 다른 사람의 대답을 이해함 에 따라 bash와 함께 버전 env:PASS에서도 안전합니다.

printf '%s\n' "$PASS"안전하지 않습니다. ps예를 들어 누군가가 명령 줄을 읽을 수 있습니다 .

6
아니요. env:PASS암호는 openssl프로세스 환경에 표시되므로 안전하지 않습니다 (프로세스 환경 에는 표시 bash되지 않지만 충분하지 않습니다). printfbash 내장이기 때문에 사용하는 것이 안전합니다.
Gilles 'SO- 악마 그만해'

echo는 bash가 내장되어 있으므로 간단한 echo 명령이 안전하지 않습니까? echo $PASS | openssl .... ps 목록에 나타나지 않습니다. 패스 할 수있는 유일한 곳은 bash 프로세스 메모리에 있습니다. 내 생각 엔?
gaoithe

1
@gaoithe 예, echo같은 이유로 printf안전합니다 ( printf내장되어 있지 않은 쉘에서는 안전하지 않습니다). 내가 사용 printf하고 사용 하지 않는 이유 는 bash 옵션에 따라 백 슬래시가 엉망 echoecho될 수 있기 때문 입니다.
Gilles 'SO- 악마 그만

8

Bash를 printf '%s\n' "$PASS"사용하면 Bash 내장 exec명령을 사용하여 소위 here 문자열을 파일 디스크립터와 연관시켜 사용하지 않고도 수행 할 수 있습니다 .

자세한 정보 는 명령 행 매개 변수의 쉘 스크립트 비밀번호 보안을 참조하십시오 .

(

# 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

죄송합니다, 이전 답변은 openssl enc 문서가 아닌 openssl 사람이 작성한 것입니다.

이 솔루션은 파이프 라인이 아니지만이 솔루션으로 인해 비밀번호가 ps에 표시되지 않습니다.

heresl 문서를 사용하면 openssl 만 암호 텍스트를 볼 수 있습니다.
중간 파일을 제거해야한다면 추적이 남아 있지 않습니다. 누군가 파이프 라인 에서이 작업을 수행하고 중간 파일을 제거 할 수 있습니까?

# 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

스위치 사용 방법을 설명하면 더 나은 대답이 될 것입니다. enc명령이 -kn스위치를 가지고 있지 않다는 것을 제외하고 ( 적어도 현재 버전에서는 스위치 가 없다는 것을 제외하고 -pass) 매우 유익하지는 않습니다. (공공은 내 것이 아닙니다.)
Gilles 'SO- 악의를 그만두십시오'

감사합니다 @ Gils, 문서를보고 내 실수를보고 다른 접근법으로 답변을 업데이트했습니다.
bsd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.