私は秘密を保存および取得するコンピュータープログラムに取り組んでおり、サーバー上でユーザーの操作なしで実行する必要があります。
gpg-agent
を使用してキャッシュされたパスフレーズを取得し、ユーザーの操作なしでgpg2 --symmetric
ファイル名を指定した場合でデータを暗号化および復号化するように、システム内のすべてを正常に設定しました。
ただし、これには、暗号化せずにデータをディスクに一時的に保存する必要があります。暗号化されていないデータをディスクに置きたくありません。そのため、ディスクファイルではなくSTDINとSTDOUTで動作するように変更しました。
私がテストしているコマンドはこれです:cat test.txt | gpg2 --symmetric -o test.gpg
。
問題は、パスフレーズをキャッシュすることができないように思われるため、毎回インタラクティブに入力する必要があることです。これは私のサーバープログラムでは機能しません。
これにgpg-preset-passphraseを使用してみました。 「KEYGRIP」が欲しいので可能かどうかはわかりませんが。私が持っている大まかなアイデアの1つは、これです。gpg2が--symmetricおよびSTDINで使用するデフォルトのキーグリップがあるかもしれません。しかし、そのアイデアがうまくいくかどうかはわかりません。
コードに--passphraseを使用してパスフレーズを指定する予定はありません。これは、コードにシークレットを格納する必要があるためです。これは、コードにアクセスできるすべてのユーザーが復号化できるようにするためです。ファイル。また、コマンドラインでパスフレーズを公開します。
私が達成しようとしていることが十分に明確であることを願っています。どんなアイデアでも大歓迎です。
私は最近これに苦労し、(gpgドキュメントとqaサイトを何度も見つけた後)これに出くわしました 2015スレッド それは答えに言及しています:
おそらく私が見逃しているのは、作成時と再利用時の両方で、対称パスフレーズに対して「cache_id」がどのように選択されるかです。要約できますか?私はコードを少し掘り下げましたが、それがどのように行われているかを整理しませんでした。
私が正しく覚えている場合(そしてロジックが変更されていない場合)、それはランダムに選択された8オクテットのソルト値です: http://tools.ietf.org/html/rfc4880#section-3.7.1.2 ==
.。
S2KソルトはキャッシュIDとして使用されます。
暗号化されたファイルのパケットを一覧表示することで、ソルトを取得できます。
$ echo | gpg --list-packets ~/myencryptedfile 2>&1 | grep -o '[0-9A-F]\{16\}'
0123456789ABCDEF
echo
はInappropriate ioctl for device
エラーを強制し、ピンエントリプロンプトをバイパスします2>&1
stderrを非表示grep -o '[0-9A-F]\{16\}'
コマンド出力からソルトを抽出しますこれで、8オクテットの16進エンコードされたソルト値が得られました。
残念ながら、それは私にとって直接はうまくいきませんでした。それで、gpgコードベースをさらに見つけた後、私は このスニペット に出くわしました:
memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf);
*s2k_cacheidbuf = 'S';
bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1);
s2k_cacheid = s2k_cacheidbuf;
核心は、2行目に付加された「S」です。私はこれが他のどこにも言及されているのを見つけることができませんでした。
だから今一緒に。ファイルを暗号化します。
$ gpg --symmetric --passphrase-fd 3 --batch --output ~/myencryptedfile <<EOF 3<<EOF3
> myencryptedcontent
> EOF
> mypassphrase
> EOF3
--passphrase-fd 3
:ファイル記述子3にパスフレーズを指定します--batch
:--passphrase-fd
で必要--passphrase-fd 3
経由で提供し、データをstdin(<<EOF
および3<<EOF3
)で暗号化することを、最初にcat
のファイルに書き込んだり、エコーしたりするよりも好みます。 stdinに(プロセスリストのスヌーピングを恐れさせます)。ドキュメント: ヒアドキュメント (EOF構文)。gpg --symmetric ... ~/myencryptedfile <<<myencryptedcontent 3<<<mypassphrase
8オクテットの16進ソルト値を取得します。
$ echo | gpg --list-packets ~/myencryptedfile 2>&1 | grep -o '[0-9A-F]\{16\}'
0123456789ABCDEF
パスフレーズのリセットがgpg-agentによって許可されていることを確認してください。
$ cat ~/.gnupg/gpg-agent.conf
allow-preset-passphrase
$ gpg-connect-agent reloadagent /bye # restart the agent after changing config
パスフレーズをプリセットします。
$ /usr/local/Cellar/gnupg/2.2.17/libexec/gpg-preset-passphrase --preset S0123456789ABCDEF <<EOF
> mypassphrase
> EOF
--preset S0123456789ABCDEF
ERR 67108924 Not supported <GPG Agent> - no --allow-preset-passphrase
を取得した場合は、allow-preset-passphrase
を~/.gnupg/gpg-agent.conf
に追加して、エージェントを再起動する必要があります(上記を参照)gpg-preset-passphrase
の場所は、システムによって異なる場合があります。そして最後に、ファイルを復号化します!
$ gpg --decrypt --pinentry-mode loopback ./myencryptedfile
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
myencryptedcontent
ノート:
gpg-preset-passphrase
を見つけるのは、システムパスのどこにもインストールされていないため(少なくとも私のインストールでは)、煩わしいことがわかりました。ただし、gpg-connect-agent
はであり、追加の手順で同じ目的に使用できます。パスフレーズを使用する前に、パスフレーズを16進エンコードする必要があります(EOFは改行を追加するため、tr -d '\n'
):$ (tr -d '\n' | hexdump -v -e '/1 "%02X"' && echo) <<EOF
> mypassphrase
> EOF
6D7970617373706872617365
$ gpg-connect-agent <<EOF
> preset_passphrase S0123456789ABCDEF -1 6D7970617373706872617365
> EOF
OK
# now decryption should work as above
$ gpg --version
gpg (GnuPG) 2.2.17
libgcrypt 1.8.5