.NETアプリのオレオレ証明書とClickOnceとSmartScreenの挙動メモ

Visual Studio 2017 Community Editionでソフトを作りClickOnceで配布する際、SmartScreenによる署名警告をなるべく減らすあれこれした。絶対忘れるヤツなのでメモ。

まず自己署名証明書では完全にはSmartScreenの警告を抑止はできない。まぁそりゃそうですわな。お金を払ってアプリ署名用証明書を買うとこれくらいするらしい。最近安くなったSSLからするとちょっとお高めな気がしますが、Webよりも偽物つかまされた時の被害も大きいので実在確認とかも厳しくて当たり前。勢いコストも上がるわってことですかね。

そしてまったく署名周りをノータッチでClickOnceインストールした場合、こんな感じで警告がでちゃいます。（Windows8だか8.1以降）。「詳細情報」をクリックすると「実行」ボタンが出現し、続行すること自体は可能。ただし証明書の「発行元」にPC名とかユーザアカウント名が入ってしまうという難点も。
![security_alert2.PNG](https://qiita-image-store.s3.amazonaws.com/0/128639/5daea603-f15c-c1ab-c33c-155f250bfbf0.png)
これがsetup.exe実行時とインストール後の.exe実行時の都合2回と、それとは別に「アプリケーションのインストール - セキュリティーの警告」というのが出ます。
![security_alert.png](https://qiita-image-store.s3.amazonaws.com/0/128639/46dd62b0-e631-f61f-6cfd-875a0dfdf6de.png)
やっぱりユーザからすると訝しいし、操作ステップも増えるので、なるべく減らしてあげたいなと思います。一方でフリー公開しているツールだったり予算がなかったりで証明書が買えない。てことで無料でできる範囲で最善を目指してみました。つまり自己署名の証明書（オレオレ証明書）を作って、まずそれをWindowsにインストールしてもらう方式です。某e-Taxとか某銀行とかもやってる由緒正しい(?)アプローチです！（あちらは予算の都合ではないと思いますw。たぶん信頼の根拠を外部民間機関なんぞに求めたくないということなのでしょう）。
こちらの一連の記事が大変参考になりました。ありがとうございます。

証明書を作成する | Do Design Space
https://sakapon.wordpress.com/2015/12/11/make-certificates/

# ■ツールのインストール
Windows 10 SDKをインストール。VS InstallerからUWPを有効にすると入るらしい。ただしUWPで作らない場合は無駄に容量がデカかったので「個別のコンポーネント」から「Windows 10 SDK 10.0.17134.0」のみ導入（いくつかのバージョンが並んでたので一番新しいっぽいのをチョイス）。
[参考] https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

# ■開発者コマンドプロンプト
開発者コマンドプロンプトを使うと環境変数とか使わなくてもパスが通るらしい。
スタートメニューで「dev」を打って「Developer Command Prompt for VS 2017」を選択。

# ■自己署名証明書を作成する。
## .cerと.pvkを作成
適当なフォルダを作成／移動して、

```
makecert -n "CN=(発行元に表示したい組織名),C=JP" -e 03/31/2028 -a sha256 -cy end -eku 1.3.6.1.5.5.7.3.3 -r -sv hogehoge.pvk hogehoge.cer
```

とした。-eの有効期限（失効日）は約10年後を指定。-ekuオプションの数値はコードサイン証明書であるという意味。-cy endは認証局ではない配布元であるということらしい。パスワードを2回と1回の計3回入力。
これでフォルダに2つのファイルが出力される。.cerは配布してインストールしてもらう公開鍵を含む証明書ファイル。.pvkは秘密鍵なので公開しちゃダメなヤツ。

## .pfxを作成
続いて.pfxファイル。公開鍵と秘密鍵のセットで受け渡しるするフォーマット。Visual Studioで署名に使用。

```
pvk2pfx -pvk hogehoge.pvk -spc hogehoge.cer -pfx hogehoge.pfx -f -pi (上記で指定したパスワード)
```

# ■証明書の個人ストアに.pfxをインストール
Visual Studioの署名画面で「ファイルから選択」から直接.pfxファイルを選ぶと、プロジェクトに登録されてしまい、Githubとかにも公開されてしまう。.ignoreとかで除外してもいいかもですが、より手軽なのは一旦Windowsアカウントの個人ストアに登録し、「ストアから選択」から選ぶのがヨサゲ（なお、ここでいう「ストア」はWindowsストアとか"お店"の意味ではなく、ローカルの証明書保管場所の意味です）。
.pfxファイルをダブルクリックしてウィザードから。先に決めたパスワードを求められる。登録できたか確認するにはスタートメニューで「証明書」などといれて「ユーザ証明書の管理」コントロールパネルを使用。ウィザードのデフォルトでおまかせで入れて行けば「個人」という下に入っているはず。

# ■Visual Studioで署名
証明書インストール後にプロジェクトを開き直さないと認識しないっぽいので注意。
「署名」ダイアログで「ストアから選択」をクリックで、先ほど入れた証明書が選択肢に出てくるはず。「証明書」欄に詳細が出るので確認してOKならClickOnce発行するだけ。

# ■ユーザに.cerをインストールしてもらった場合の挙動
ユーザが.cerファイルを取得してインストールする場合、インストール先のストアによって挙動がかわります。上記のようにおまかせで「個人」ストアに入れても意味はなさげ。この画面で「証明書をすべて次のストアに配置する」を選び、参照から下記ストアを選びます。
![cer_install3.PNG](https://qiita-image-store.s3.amazonaws.com/0/128639/1006ca44-01b1-9211-d7e3-38dbd0a5f7d8.png)


## 「信頼されたルート証明機関」にインストールした場合
SmartScreenの警告画面で「詳細」を押した時に、発行元が「不明な発行元」だったのがこちらで設定した名称を表示できちょっと安心感が出ます。あくまで雰囲気だけで、実際には誰にでも同名の証明書を作れるのでセキュリティとしての意味は薄いでしょう。また、こんな警告も出ます。拇印情報を配布サイトに記載しておいて照合してもらうように促せば、ちょっとだけ差し替え攻撃に強くなるかな？くらい。
![cer_install8.png](https://qiita-image-store.s3.amazonaws.com/0/128639/84b78cbe-0342-5669-fc1a-394f5bed2cd6.png)

## 「信頼された発行元」にインストールした場合
冒頭の3回の警告のうち、「アプリケーションのインストール - セキュリティ警告」がなくなり、SmartScreenも2回から1回に減る模様。たぶん、setup.exeへの警告はそのままで、アプリの初回起動時のがスキップされてるんだと思います。

# まとめ
結局のところ、無料で誰でも作れる自己署名証明書では、どこかしらで警告が出てしまいます。さらに証明書をインストールしてもらうという労力（しかもちょっとわかりにくい）がユーザ側に発生し、操作ステップ数的にもあんまりメリットはない感じ。ただし1つの証明書でたくさんのサブツールを配布する場合は、最初だけ手間をかければ後が楽になるのでアリかも知れません。
また、[証明書のインストール操作自体を.NETのコードで書ける](http://www.atmarkit.co.jp/fdotnet/dotnettips/844addcert/addcert.html)みたいなので、その気になればもう少しだけユーザに楽させてあげられるかも知れません（e-Taxの事前準備セットアップとかでやってるのがこれ？）。

本記事を「ほら証明書代ケチると、ユーザがこんな面倒くさい思いすることになりますよ？」とステークホルダーを説得する材料となれば幸いです。