none
VB.NETからのGPGコマンド入力について RRS feed

  • 質問

  • 環境 = Win7、VS2013

    ①Dim p As New System.Diagnostics.Process()

    ②p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec")
    ③p.StartInfo.UseShellExecute = False
    ④p.StartInfo.RedirectStandardOutput = True
    ⑤p.StartInfo.RedirectStandardInput = False
    ⑥p.StartInfo.CreateNoWindow = False
    ⑦p.StartInfo.Arguments = "gpg --passphrase ""password"" C:\TEST\a.gpg"
    ⑧p.Start()

    ⑨Dim results As String = p.StandardOutput.ReadToEnd()

    ⑩p.WaitForExit()
    ⑪p.Close()

    GPGにて暗号化したファイルをVB.NETからコマンド入力して復号化したいと考えています。
    過去に同じような質問されていた方がおりましたが、解決策を記載されていなかったので再度投稿させて頂きました。

    現在、⑨にて止まってしまい、原因はパスワード入力待ちだと思うのですが、
    『--passphrase』で指定しているにも関わらず効かなくて行き詰ってしまいました。

    DOSを起動させ、手入力で同じコマンドを入力した場合、同じファイルであると1回目だけパスワード入力を聞かれ、
    その後は入力したコマンドでもパスワードが聞かれない状態です。

    バッチプログラムであり、実際のファイル名は日時が含まれる為、同じファイル名はあり得ません。
    その為、パスワード入力を含め自動化したく、アドバイスをお願い申し上げます。 

    • 編集済み kong0214 2014年11月18日 11:24
    2014年11月18日 11:21

回答

  • 「--batch」オプションを付ける必要があると思うのですが、付けても同じ現象になるのでしょうか?

    駄目なら「--passphrase-fd n」の方を試してみるとか。

    それと、「--passphrase string」の場合、タスクマネージャーなどでパスフレーズを見れてしまいますが、問題ない環境なのでしょうか?

    • 回答としてマーク kong0214 2014年11月19日 1:07
    2014年11月18日 15:36
  • --passphrase-fdはパスフレーズをファイルディスクリプタ(主に標準入力)から受け取るための引数なので、使用するならRedirectStandardInputをtrueにして、Startした後のStandardInputにパスフレーズを書き込んでください。

    http://sonic64.com/2004-01-08.html

    ちちびんたリカさんの提案の一つ目は、--passphraseオプションに加えて--batchオプションを指定するのはどうか、というもので、--passphrase-fdはその一つ目の提案が駄目だった場合の話です。

    // ところで本件とはあんまり関係ないですが、何で一旦cmd.exeを経由してるんでしょうか。直接ProcessStartInfo::FileNameにgpgを指定したら駄目?

    • 回答としてマーク kong0214 2014年11月19日 2:12
    2014年11月19日 1:28
  • 『gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg』をdosにて手入力した場合、ファイルを復号化しているかのような意味不明な文字がDOS画面に滝のように流れ、途中で止まってしまい、応答がなくなります。また、ファイルは復号化出来ていません。

    gpgについては詳しくないですが、--outputオプションを使わない限り、復号結果は標準出力、つまりコンソール画面に出されるのでは?(標準出力をcmd.exeのリダイレクト機能でファイル出力する場合もあるでしょうけど)

    // あと、WindowsにDOSが搭載されなくなって久しいので、「コマンドプロンプト」「コンソール」などと表現された方が良いです。

    ちなみにご提案頂きた記載の仕方は下記の通りであっていますか?

    Dim psi As New System.Diagnostics.ProcessStartInfo()
    psi.FileName = "C:\Program Files\GNU\GnuPG\pub\gpg.exe"  ←環境変数では「pub」まで記載されています。
    psi.Arguments = """gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg"""
    System.Diagnostics.Process.Start(psi)

    Argumentsにgpgは不要ですし、引数全体を二重引用符で囲ってはいけませんが、全体的にはそんな感じです。

    なお、環境変数はEnvironment.GetEnvironmentVariableメソッドEnvironment.ExpandEnvironmentVariablesメソッドなどで展開することもできます。また、cmd.exe gpgでgpgを起動できるなら、FileNameもgpgだけでもいけるかもしれません。

    • 回答としてマーク kong0214 2014年11月19日 3:57
    2014年11月19日 2:58
  • 少し本題と逸れるのですが、過去のちちびんたリカさんから頂いたアドバイスで
    >「--passphrase string」の場合、タスクマネージャーなどでパスフレーズを見れてしまいますが、問題ない環境なのでしょうか?
    につきまして、string部をXMLの外だしにして、コマンド部は変数を当てる予定なのですが、見えてしまうのでしょうか?


    そのようにすればソース上からは消すことができますが、動作上は変数が展開された結果がコマンドとして実行されますので、結果は同じになります。
    • 回答としてマーク kong0214 2014年11月19日 4:29
    2014年11月19日 4:17
  • タスクマネージャーの[表示]→[列の選択]から「コマンドライン」をチェックすると、各コマンドがどういう引数を伴って実行されているか表示されます。

    「--passphrase string」を使う限り避けられませんので、問題になる場合は「--passphrase-fd n」または「--passphrase-file file」の使用を検討してください。

    なお、「--batch」オプションを付ける必要がある事や「--passphrase string」にはマルチユーザーシステム上でセキュリティにかかわる問題があることなどは、gpgのマニュアルに書かれています。

    お使いのgpgのバージョンが書かれていませんが、現在最新のGpg4win 2.2.2の場合は「C:\Program Files (x86)\GNU\GnuPG\share\gnupg\gpg2.man」にマニュアルがインストールされていますので、よく読まれることをお勧めします。

    • 回答としてマーク kong0214 2014年11月20日 11:27
    2014年11月19日 16:57

すべての返信

  • 「--batch」オプションを付ける必要があると思うのですが、付けても同じ現象になるのでしょうか?

    駄目なら「--passphrase-fd n」の方を試してみるとか。

    それと、「--passphrase string」の場合、タスクマネージャーなどでパスフレーズを見れてしまいますが、問題ない環境なのでしょうか?

    • 回答としてマーク kong0214 2014年11月19日 1:07
    2014年11月18日 15:36
  • お世話になります。

    ⑦p.StartInfo.Arguments = "gpg --passphrase ""password"" C:\TEST\a.gpg" ⇒

    ⑦p.StartInfo.Arguments = "gpg --batch --passphrase-fd 0 --decrypt C:\TEST\a.gpg"

    に変更して実行してみましたが、⑨で止まってしまいます。

    ちなみに、DOSを起動させ『gpg --batch --passphrase-fd 0 --decrypt C:\TEST\a.gpg』を入力した場合も返ってこなくなるので、そもそもコマンドが間違っているのかな?と思っているのですが、ネットで検索しても同様の例が見られ、行き詰ってしまいました。

    どうかお知恵を貸して頂き度、何卒宜しくお願い申し上げます。

    2014年11月19日 1:06
  • --passphrase-fdはパスフレーズをファイルディスクリプタ(主に標準入力)から受け取るための引数なので、使用するならRedirectStandardInputをtrueにして、Startした後のStandardInputにパスフレーズを書き込んでください。

    http://sonic64.com/2004-01-08.html

    ちちびんたリカさんの提案の一つ目は、--passphraseオプションに加えて--batchオプションを指定するのはどうか、というもので、--passphrase-fdはその一つ目の提案が駄目だった場合の話です。

    // ところで本件とはあんまり関係ないですが、何で一旦cmd.exeを経由してるんでしょうか。直接ProcessStartInfo::FileNameにgpgを指定したら駄目?

    • 回答としてマーク kong0214 2014年11月19日 2:12
    2014年11月19日 1:28
  • お世話になります。

    『gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg』をdosにて手入力した場合、
    ファイルを復号化しているかのような意味不明な文字がDOS画面に滝のように流れ、途中で止まってしまい、応答がなくなります。
    また、ファイルは復号化出来ていません。

    『gpg --passphrase "password" --decrypt C:\TEST\a.gpg』をdosにて手入力した場合、は普通にパスワードが聞かれます。

    『--batch』の使い方が間違っているのでしょうか?

    また、cmd.exeを経由しなければならない理由はありません。
    他に記載の仕方が判らなかっただけで御座います。


    ちなみにご提案頂きた記載の仕方は下記の通りであっていますか?

    ---------------記---------------

    Dim psi As New System.Diagnostics.ProcessStartInfo()
    psi.FileName = "C:\Program Files\GNU\GnuPG\pub\gpg.exe"  ←環境変数では「pub」まで記載されています。
    psi.Arguments = """gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg"""

    System.Diagnostics.Process.Start(psi)

    以上、何卒宜しくお願い申し上げます。

    2014年11月19日 2:24
  • 『gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg』をdosにて手入力した場合、ファイルを復号化しているかのような意味不明な文字がDOS画面に滝のように流れ、途中で止まってしまい、応答がなくなります。また、ファイルは復号化出来ていません。

    gpgについては詳しくないですが、--outputオプションを使わない限り、復号結果は標準出力、つまりコンソール画面に出されるのでは?(標準出力をcmd.exeのリダイレクト機能でファイル出力する場合もあるでしょうけど)

    // あと、WindowsにDOSが搭載されなくなって久しいので、「コマンドプロンプト」「コンソール」などと表現された方が良いです。

    ちなみにご提案頂きた記載の仕方は下記の通りであっていますか?

    Dim psi As New System.Diagnostics.ProcessStartInfo()
    psi.FileName = "C:\Program Files\GNU\GnuPG\pub\gpg.exe"  ←環境変数では「pub」まで記載されています。
    psi.Arguments = """gpg --batch --passphrase "password" --decrypt C:\TEST\a.gpg"""
    System.Diagnostics.Process.Start(psi)

    Argumentsにgpgは不要ですし、引数全体を二重引用符で囲ってはいけませんが、全体的にはそんな感じです。

    なお、環境変数はEnvironment.GetEnvironmentVariableメソッドEnvironment.ExpandEnvironmentVariablesメソッドなどで展開することもできます。また、cmd.exe gpgでgpgを起動できるなら、FileNameもgpgだけでもいけるかもしれません。

    • 回答としてマーク kong0214 2014年11月19日 3:57
    2014年11月19日 2:58
  • お世話になります。

    Dim psi As New System.Diagnostics.ProcessStartInfo()
    psi.FileName = "gpg"
    psi.Arguments = "-o C:\TEST\o.stdf --batch --passphrase ""password"" --decrypt C:\TEST\a.gpg"
    System.Diagnostics.Process.Start(psi)

    上記で実現出来ました。
    的確なアドバイス誠に有難う御座います。
    本当に助かりました。

    また、DOSではなくコマンドプロンプトにするよう努めていきます。
    重ねてお礼申し上げます。

    少し本題と逸れるのですが、過去のちちびんたリカさんから頂いたアドバイスで
    >「--passphrase string」の場合、タスクマネージャーなどでパスフレーズを見れてしまいますが、問題ない環境なのでしょうか?
    につきまして、string部をXMLの外だしにして、コマンド部は変数を当てる予定なのですが、見えてしまうのでしょうか?

    以上、何卒宜しくお願い申し上げます。

    2014年11月19日 3:57
  • 少し本題と逸れるのですが、過去のちちびんたリカさんから頂いたアドバイスで
    >「--passphrase string」の場合、タスクマネージャーなどでパスフレーズを見れてしまいますが、問題ない環境なのでしょうか?
    につきまして、string部をXMLの外だしにして、コマンド部は変数を当てる予定なのですが、見えてしまうのでしょうか?


    そのようにすればソース上からは消すことができますが、動作上は変数が展開された結果がコマンドとして実行されますので、結果は同じになります。
    • 回答としてマーク kong0214 2014年11月19日 4:29
    2014年11月19日 4:17
  • お世話になります。

    つまり、パスワードが見えてしまうのは仕方ないという事でしょうか?
    XMLへの固定値の外だしは規約としてあるので、変更できないのですが、
    私個人での作り方次第で、少しでも良いものが出来るのでしたら
    是非ご教示頂き度。

    また、タスクマネージャから見えるとはどうやって見えるんですか?

    何卒宜しくお願い申し上げます。

    2014年11月19日 4:36
  • タスクマネージャーの[表示]→[列の選択]から「コマンドライン」をチェックすると、各コマンドがどういう引数を伴って実行されているか表示されます。

    「--passphrase string」を使う限り避けられませんので、問題になる場合は「--passphrase-fd n」または「--passphrase-file file」の使用を検討してください。

    なお、「--batch」オプションを付ける必要がある事や「--passphrase string」にはマルチユーザーシステム上でセキュリティにかかわる問題があることなどは、gpgのマニュアルに書かれています。

    お使いのgpgのバージョンが書かれていませんが、現在最新のGpg4win 2.2.2の場合は「C:\Program Files (x86)\GNU\GnuPG\share\gnupg\gpg2.man」にマニュアルがインストールされていますので、よく読まれることをお勧めします。

    • 回答としてマーク kong0214 2014年11月20日 11:27
    2014年11月19日 16:57