Bash에서 >1개 프로그램의 비밀번호를 전달하는 안전한 방법

Bash에서 >1개 프로그램의 비밀번호를 전달하는 안전한 방법

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그렇다면 두 인스턴스 모두에 비밀번호를 안전하게 전달하려면 어떻게 해야 할까요 ?

답변1

입력 시 별도의 파일 설명자에 비밀번호를 전달합니다(암호화용으로 한 번, 암호 해독용으로 한 번). 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사용할 수 있습니다.-pass토론openssl열린 파일 설명자에서 읽을 비밀번호를 알려줍니다 .

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

답변2

printf '%s\n' "$PASS"Bash를 사용하면 소위 here 문자열을 파일 설명자와 연결하기 위해 Bash 내장 명령을 사용하지 않고도 이 작업을 수행할 수 있습니다 exec.

자세한 내용은 다음을 참조하세요.명령줄 매개변수에 대한 쉘 스크립트 비밀번호 보안.

(

# 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

)

답변3

죄송합니다. 이전 답변은 openssl enc 문서가 아닌 openssl man에서 나왔습니다.

이 솔루션은 파이프가 아니지만 이 솔루션이 ps에 비밀번호가 표시되는 것을 방지한다고 생각합니다.

여기 문서를 사용하면 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

답변4

나는 완전한 재설정을 수행하고 구성 파일을 보존하기 위해 이 작은 bash 스크립트를 만들었습니다. 강제 푸시는 GitHub 저장소를 효과적으로 다시 생성합니다.

#!/bin/bash
tfile=$(mktemp /tmp/config.XXXXXXXXX)
GITCONF=".git/config"
commitmsg=${1:-git repository initialised}
if [ -f $GITCONF ]; then
   mv .git/config tfile
   rm -rf .git
   git init .
   mv tfile .git/config
   git add .
   git commit -a -m "${commitmsg}"
   git push -f
else
   echo "Warning: No git config file found. Aborting.";exit;
fi

관련 정보