DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ClickOnce配布後にapp.configファイルが読み込めてしまう現象を回避したい

環境/言語:[Windows7 VB.net]
分類:[.NET]

いつもお世話になっております。

ClickOnceで配置したアプリケーションがはじめて起動された時にapp.config
ファイルを暗号化していますが、ClickOnceでapp.configファイルがローカルの
Cドライブにコピーされてからアプリケーションで暗号化するまでの間にわずか
がら時間があるため、その間に暗号化されていないデータを読み取られてしまう可能性
があります。」

この点を回避する方法はないでしょうか?

なお、暗号化は下記のようなコードで行っており、
スタートアップフォームのLoad時に呼び出しています。

        Dim config As System.Configuration.Configuration = _
         System.Configuration.ConfigurationManager.OpenExeConfiguration("MY_APP.exe")

        Dim section As System.Configuration.ConnectionStringsSection = DirectCast( _
            config.GetSection("connectionStrings"),  _
            System.Configuration.ConnectionStringsSection)

        If section.SectionInformation.IsProtected = False Then

            section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
            config.Save()
        End If

※配置された直後のapp.configファイルを別のプロセスから読みに行くのは
簡単なコーディングで可能でしたので、あえてここにアップしません。

※配置後のCドライブ内に生成されるアプリケーション・フォルダは、暗号のようなパス
(例:acvbdf5454gd1257...) になっていますが、これはClickOnceの初回配布時は
分からないとしても、2回目以降のバージョンアップ時には1回目と同じ場所になるので
つかまえることができるという前提です。

※当質問の意図は(当然ですが)自分のアプリケーションの脆弱性を無くすことが目的です。

宜しくお願いいたします。
■No32084に返信(kane123さんの記事)
> この点を回避する方法はないでしょうか?
>
ClickOnceで配布用ファイルを作成する前に暗号化しておくというのはどうでしょう。
配布方法によってはsetup.exeと同位置にあるフォルダの中身をテキストエディタで見れば(*.deploy)平文で置かれているだけというのは分かるのですから。
または、設計として外部に漏らしたくない情報は初期値として保存しないとか。
※今回の例だとユーザー名とパスワード?
 ウィンドウズ認証なら接続文字列が外部に出ても問題なさそうですが。
回答ありがとうございます。

理解が不足していたらすみません。

>ClickOnceで配布用ファイルを作成する前に暗号化しておくというのはどうでしょう。

配布用の.exe内に暗号化された接続文字列を持ち、実行時に複合化
するという方法でしょうか?これであれば、(おそらく)
暗号化キーを使った暗号化ということになると思います。

http://dobon.net/vb/dotnet/string/encryptstring.html

つまり、.exeを逆コンパイルされれば、暗号化された接続文字列と
暗号化キーは拾い出せるので、接続文字列は暴かれてしまう
と思います。

app.configでやる場合は、PCごとに固有の暗号化を行うので、
よりセキュリティが強い、と思われるのでapp.configで
やりたいという判断に至りました。
(ただ、それが上記のように読めてしまうというのが問題なので
すが・・・)
2014/01/21(Tue) 22:45:14 編集(投稿者)

何から接続文字列を守りたいのでしょうか?

■No32086に返信(kane123さんの記事)
> 回答ありがとうございます。
> app.configでやる場合は、PCごとに固有の暗号化を行うので、
> よりセキュリティが強い、と思われるのでapp.configで
> やりたいという判断に至りました。

PC ごとの固有の鍵で暗号化するため、PC に展開されるまでは暗号化できません。
また、PC ごとの固有の鍵であるため、別のアプリでもその同じ鍵を使うことができます。
つまり、プログラムを書いて、その環境で実行すれば逆コンパイルと同様に見ることができると思われます。
(この暗号化は、config ファイルだけを盗まれても大丈夫というレベルのもののはずなので、config ファイルとその暗号鍵を有するマシン・ユーザーが揃っていればどのプロセスでも復元できる、つまり、「実行ユーザーに知られたくない」という目的で使う暗号化ではないということだと考えています)

参考
http://stackoverflow.com/questions/895739/net-encryption/895856#895856


結局のところ、誰からどの程度守りたいのかによって選択肢は変わってきます。
開発者の秘めた鍵をユーザーから見えないようにするという話であれば、難読化、HASP などによる暗号ソリューションを考えていくことになりますが、究極的には守れません。
(ユーザー環境で実行する以上、どこかのタイミングでメモリ上には元の文字列が存在するため)

回答ありがとうございます。

>何から接続文字列を守りたいのでしょうか?

悪意ある第三者からです。アプリの用途は社内用の業務アプリで、
ActiveDirectory外のユーザーも配布対象、という状況です。つまり
なんらかの悪意をもったユーザーを想定する必要があるという
状況です。


>開発者の秘めた鍵をユーザーから見えないようにするという話であれば、難読化、HASP などによる暗号ソリューションを考えていくことになりますが、究極>的には守れません。
>(ユーザー環境で実行する以上、どこかのタイミングでメモリ上には元の文字列が存在するため)

そうだったのですね。もやもやが晴れました。
 つまり、DBとの通信を行うようなアプリケーション(クラサバ)においては、
セキュリティが完全に保証されるようなものは、アプリケーションをサーバーサイドで
動かすようなもの(クライアントからはミドルウェア等を通してアプリケーションを
見に行くような)以外はありえない、ということになりますかね?
解決済み!
■No32091に返信(kane123さんの記事)
>  つまり、DBとの通信を行うようなアプリケーション(クラサバ)においては、
> セキュリティが完全に保証されるようなものは、アプリケーションをサーバーサイドで
> 動かすようなもの(クライアントからはミドルウェア等を通してアプリケーションを
> 見に行くような)以外はありえない、ということになりますかね?

データベースサーバーの接続パスワードを秘匿したいということであれば、おっしゃられているように、サーバーサイドでロジックを実行するようなサービス提供型でないと難しいでしょう。

なお、サービスは不正なアプリから呼び出される恐れもあるので、渡されたリクエストが妥当なものか検証するというプロセスが必要になります。

// 悪意ある行為から守るのは手間がかかるし、難しいことだと思います。
// あとはどこまで手間をかけて、リスクを下げておくか。
解決済み!
Azuleanさん、ありがとうございました。
おかげさまで方向性がまとまりそうです。

解決済みとさせていただきます。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板