2

サードパーティから GPG 暗号化ファイルを受け取ります。暗号化されたファイルを見つけて復号化し、暗号化されたファイルを削除する C# プログラムを変更しています。復号化部分でフェーズフレーズを要求する場合を除いて、すべて機能します。パスフレーズを知っていて、入力すると機能します。プロンプトが表示されないように、コマンドでパスフレーズを渡す必要があります。

string CommandText = string.Format("echo {0}|gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd 0 -o {3} -d {4}",
                passPhrase, publicKeyRingPath, secretKeyRingPath, outputFullPath, encryptedFilePath);

私も試しました:

    string CommandText = string.Format("gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase {0} -o {3} -d {4}",
    string CommandText = string.Format("gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd {0} -o {3} -d {4}",

他のいくつかのバリエーションと同様に。

これは Windows 2.1.0.57899 用の GnuPG を実行しています

問題が別の場所にある場合に備えて、主に私の前任者によって書かれた一連のコードを次に示します。

public bool decryptInputFile(string encryptedFilePath, string outputFullPath, out string message)
{
    message = "decryptInputFile: Started";
    try
    {
        ProcessStartInfo psi = new ProcessStartInfo("cmd.exe")
        {
            CreateNoWindow = true,
            UseShellExecute = true,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            WorkingDirectory = decryptPath,
        };

        message = "decryptInputFile: PSI Initialized";
        using (Process process = Process.Start(psi))
        {
            string CommandText = string.Format("echo {0}|gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd 0 -o {3} -d {4}",
                                passPhrase, publicKeyRingPath, secretKeyRingPath, outputFullPath, encryptedFilePath);
            process.StandardInput.WriteLine(CommandText);
            process.StandardInput.Flush();
            process.StandardInput.Close();
            process.WaitForExit();
            process.Close();
            process.Dispose();
            message = "decryptInputFile: Success";


            //These processes don't close and it keeps the file from being deleted.
            foreach (Process P in Process.GetProcessesByName("gpg")) { P.Kill(); }
            foreach (Process P in Process.GetProcessesByName("gpg2")) { P.Kill(); }

        }
    }
    catch (Exception x)
    {
        // If there was an error, we're going to eat it and just let the user know we failed.
        message = "decryptInputFile: Error: " + x.Message;
        string errMessage = "ERROR: could not decrypt. " + x.Message + "\r\n";
        File.AppendAllText(System.Configuration.ConfigurationSettings.AppSettings["LogPath"], errMessage);

        return false;
    }

    if (File.Exists(outputFullPath) && File.Exists(encryptedFilePath))
    {
        File.Delete(encryptedFilePath);
    }
    return File.Exists(outputFullPath);
}
4

2 に答える 2

6

問題

GnuPG 2 を使用しています。GnuPG 2 では、--passphrase*オプションと--batch.

使用する--batch

--passphrase*オプションは、スクリプト作成に使用するためのものです。GnuPG 2 はそれらを (おそらくゆっくりと非推奨にするために) --batchGnuPG が対話を行わないモードに制限します (たとえば、パスフレーズやその他の「対話」を要求します)。

これはまだ可能ですが、gpg-agent代わりにパスワードの事前設定を使用することをお勧めします。これにより、アプリケーション コードからパスフレーズを完全に削除できます。--passphrase(GnuPG が実行されている限り、システム上のすべてのユーザーがそれを読み取ることができます!) および--passphrase-file(パスフレーズはハードディスクに保存されます。パーミッションに注意してください)の影響に注意してください。

パスフレーズの事前設定

GnuPG 2 で推奨される方法はgpg-agent、GnuPG が大きく依存している にパスフレーズを事前設定することです。GnuPG 2.1 の場合、event は秘密鍵とパスフレーズの操作を完全に単独で処理します。

しかし、あなたを救うために、GnuPG 2 は新しいツールgpg-preset-passphrase. Debian Linux では に隠れています/usr/lib/gnupg2/が、Windows ではどこに保存されているかわかりません。

からman gpg-preset-passphrase:

gpg-preset-passphrase、実行中の内部キャッシュにgpg-agentパスフレーズをシードするためのユーティリティです。これは主に、通常のpinentryツールが使用されず、使用されるキーのパスフレーズがマシンの起動時に与えられる無人マシンに役立ちます。

[...]

gpg-preset-passphraseこの方法で呼び出されます:

gpg-preset-passphrase [options] [command] cacheid

cacheidパスフレーズを設定またはクリアする必要があるキーを識別する 16 進文字の 40 文字のキーグリップです。[...]

次のコマンド オプションのいずれかを指定する必要があります。

--preset
    Preset a passphrase. This is what you usually will use.
    gpg-preset-passphrase will then read the passphrase from stdin.

まとめとして、アプリケーションの GnuPG を初期化するとき (および構成されたキャッシュ時間に対応する間隔で) を実行します。gpg-preset-passphrase --preset [fingerprint]これにより、stdin からパスフレーズが読み取られるか、さらに--passphrase passphraseオプションを使用してクエリで直接設定されます。エコーまたは--passphraseアプローチの両方を使用する場合、他のシステム ユーザーがプロセスを一覧表示してパスフレーズを取得する可能性があることに注意してください。C# からプロセスの stdin に直接書き込むことをお勧めします。

于 2015-02-12T17:48:22.263 に答える
1

受け入れられた答えを試しましたが、うまくいきませんでした。

私はオンでしたUbuntu 20.04.1 LTS

私のために働いた私の答えをチェックしてください

于 2021-01-27T12:32:21.540 に答える