web-dev-qa-db-ja.com

stdinを介してopensslにパスワードを安全に渡す

次のコマンドを使用して、opensslでファイルを暗号化できることがわかっています。

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass stdin

パスワードはstdinから読み取られます。そのため、事前にパスワードを入力するには、先頭に追加するだけです。

echo "someGoodPassword" |

上記のコマンドに。私の質問は:どうすればこれをより安全に行うことができますか?上記の方法は十分に安全に見えません。

この問題をよりよく理解できるように、これについていくつかコメントをいただければ幸いです。

15
Enchilada

使用するほとんどすべてのメカニズムはルートによってスヌープ可能であるため、これを覚えておいてください。

エコーオプションは「ps」リストに表示されるため、通常のユーザーがパスワードをスヌーピングして見つけることに対して脆弱になります。

-pass file:filenameを使用してファイルを使用できるため、次を使用できます。

sumask=$(umask)
umask 077
rm -f passfile
cat >passfile <<EOM
someGoodPassword
EOM
umask $sumask

これによりファイルが作成され、他のアカウントでは読み取れません(ただし、rootでは読み取り可能です)。スクリプトはパスファイルの作成に1回だけ使用されていると想定されます。プロセスを繰り返すと、ファイルに含まれる傾向があるため、他のユーザーが読み取れないようにファイルをchmod go-rwxする必要があります。

次に、以下を使用します。

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass file:passfile

事前に作成されたパスワードファイルを使用して暗号化を実行します。

他のメカニズムは、環境変数を使用するための-pass env:ENVVARです(これもトリックであることを明かさずにそこに入れる)

18
Petesh

ショートバージョン

名前付きパイプを使用します。

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass file:<( echo -n "someGoodPassword" )

ロングバージョン

名前付きパイプを使用します。あなたはそれをbashで作成することができます

<( *output* )

例えば.

<( echo -n "content" ) # without -n echo will add a newline

名前付きパイプ、通常はFIFOキューを開き、プロセスリストに次のようなものが表示されます。

/dev/fd/63

現在のユーザーのみが読み取り可能で、読み取り後に自動的に閉じられるため、アクセス許可やディスクのクリーンアップについて心配する必要はありません(プログラムがクラッシュするとパイプが閉じますが、ファイルは別の回答で提案されているように、ディスク上にとどまります)。

このようにして、コマンドがそれを読み取った直後に、タスクが完了するのを待たずに、可能な限り最速の方法で閉じます(私はテストを行いました:数ギガバイトを暗号化し、名前付きパイプを読み取ろうとします(プロセスリストに表示されます) ):opensslの暗号化に時間がかかっても、名前付きパイプは即座に閉じます)。

コメントについて

このパスワードを取得するために2番目のアプリによってコンピューターが侵害された場合、ユーザーはいくつかの深刻なセキュリティ問題を心配する必要があります。実際、それは私自身のソフトウェアを攻撃するために特別に設計されたソフトウェアである可能性があります

コンピューターがハッキングされ、攻撃者が同じユーザー権限を持っている場合は、これで完了です。たとえば、攻撃者は.bashrcをエイリアスopensslに簡単に変更して、すべてを実際のopensslに処理する前に、パスワードとデータをコピーする架空の「evil-openssl」を開始し、誤った安心感を残す可能性があります。

とは言うものの、私はセキュリティの専門家ではないので、誰かが私を忘却に反対する(そしてその理由を教えてください)場合は、大歓迎です。

15
Riccardo Galli

私が正しく理解していれば、あなたのコンサートについて

$ echo "someGoodPassword" | openssl (...) -pass stdin

パスワードは、プロセスリストにすべてのユーザーに短時間表示されます。これは、bashの<<<リダイレクトで簡単に回避できます(ただし、単純な古いPOSIXシェルでは機能しません)。

$ openssl (...) -pass stdin <<<"someGoodPassword"

この構成は変数補間(<<<"$password")をサポートし、コマンド出力はさらにパイプするか、通常どおりファイルにリダイレクトできます。

3
firegurafiku

パスワードのパススルーにはいくつかの方法を使用できます: https://www.openssl.org/docs/man1.0.2/apps/openssl.html#PASS-PHRASE-ARGUMENTS

@Peteshが言ったように、rootはすべてを読むことができます!

したがって、パスワードを任意のcommon(!)ファイルに書き留めると、たとえば、.

  • 安全な許可を得て一時ファイルに
  • またはスクリプトにあなたのechoトリックをパイプに何をしますか

rootユーザーはこれを見つけることができます!

/procを介して利用可能なすべてのものを使用することを好まない(たとえば、psによって)

したがって、使用しないでください...

openssl aes-256-cbc ... -passin 'pass:someGoodPassword'

または

PASSWORD='someGoodPassword'
openssl aes-256-cbc ... -passin 'env:PASSWORD'`

最良の解決策

  • システムにプレーンテキストでパスワードを保存しないでください(パスワードマネージャーを使用するなど)
  • パイプ/ FIFOを介してパスワードをopensslに渡します。

    password_manager get_password | openssl aes-256-cbc ... -passin 'stdin'
    

    または

    # https://stackoverflow.com/a/7082184/1108919
    password_manager get_password >&3
    openssl aes-256-cbc ... -passin 'fd:3'
    

    または

    openssl aes-256-cbc ... -passin "file:<(password_manager get_password)"
    
1
andras.tim

パスワードをbashまたは他のスクリプトファイルに入れ、600のアクセス許可を作成します。これにより、ファイルを表示できるのはあなただけになり、パスワードはどこにも公開されません。

1