続３・REST Webサービス作成メモ（Web.configの暗号化）

#前回までのあらすじ
C言語しか知らない筆者がREST Webサービスを作成しようと思い立ち、サービス側プログラムと、クライアント側プログラムの作成、SSL有効化まで辿り着きました。

* [REST Webサービスの作成が僕には難しすぎたので、誰にでも分かるよう手順を残す。](http://qiita.com/yz2cm/items/8e7790026b7697843219)
* [続・REST Webサービスの作成が僕には難しすぎたので、誰にでも分かるよう手順を残す。（クライアント編）](http://qiita.com/yz2cm/items/46d8e87a39f844904ea7#_reference-8cb314d5483d8488ab3d)
* [続２・REST Webサービス作成メモ（IIS ExpressのSSL有効化編）](http://qiita.com/yz2cm/items/8c0bbbf16414b072e104)

今回は、`Web.config`に設定値を平文で持たせず、暗号化して持たせる。です。

#本記事のゴール

* 設定値は`Web.config`で一括して定義するが、シークレットキー等のデリケートな設定値だけは平文で書き込まず、暗号化済みの文字列を持たせる。
* ただしプログラムから使用する場合は、暗号化前のキーを透過的に使用できるようにする（復号処理をゴリゴリ書きたくない）。

#１．Web.configへの設定値の定義

例えば、何かのAPIのシークレットキー「`p@5k#2Az`」を`Web.config`に定義したとします。

```xml:Web.config
<configuration>
  <appSettings>
    <add key="SecretKey" value="p@5k#2Az" />
  </appSettings>
<!-- 以下略 -->
```

平文かあ…いけてない。そこで、上記箇所を暗号化します。

#２．設定値の暗号化

`Web.config`の暗号化には、`aspnet_regiis.exe`コマンドを使用します。

* このコマンドを実行すると、`Web.config`ファイルの任意のセクションが暗号化されます（暗号化後のファイルが新規に生成されるわけではなく、元の`Web.config`の該当箇所が、暗号化後の文字列に更新される）。


##２．１．aspnet_regiisの場所
このコマンドのパスは、.Net Frameworkのバージョンによって異なるそうです。僕の環境では以下に存在しました。

`C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe`

##２．２．aspnet_regiisの使用方法

###２．２．１．暗号化する場合
```:暗号化
aspnet_regiis.exe -pef <セクション名> <Web.configが格納されたフォルダのパス名>
```
* `-pef`オプションには、暗号化の対象としたい**セクション名**（例：`appSettings`）を指定します
* 第二引数には`Web.config`が格納されたフォルダのパス名を指定します。
* 同時に複数のセクションを指定することはできないようです（`-pef "appSettings1" -pef "appSettiongs2"`とか、`-pef "appSettings1" "appSettiongs2"`はできない）。複数セクションを暗号化したい場合、**セクションごとにコマンドを実行する**必要があります。
* 暗号化後の`Web.config`を、さらに暗号化した場合、二重に暗号化されてしまうことはない？→問題ありません。「暗号化しています...成功しました！」というメッセージが出て、暗号化文字列は再生成されますが、復号を2回しなければならない、とかそういうことはありません。

以下、暗号化の例です。

```bat:コマンドの実行例（コマンドプロンプト）
>"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe" -pef "appSettings" "C:\Users\yz2cm\OneDrive\Documents\Visual Studio 2017\Projects\ProductsApp\ProductsApp"
Microsoft(R) ASP.NET IIS 登録ツール バージョン 4.0.30319.0
ローカル コンピューターの ASP.NET をインストールおよびアンインストールするための管理ユーティリティです。
Copyright(C) Microsoft Corporation.  All rights reserved.
構成セクションを暗号化しています...
成功しました!
```

`Web.config`を開くと、なんか訳の分からないことになっています。無事、暗号化に成功したようです。

```xml:Web.config（暗号化済み）
<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  https://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <appSettings configProtectionProvider="RsaProtectedConfigurationProvider">
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
      xmlns="http://www.w3.org/2001/04/xmlenc#">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
          <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <KeyName>Rsa Key</KeyName>
          </KeyInfo>
          <CipherData>
            <CipherValue>Ka4kiku9OrXNJsKhINNVCCPz5hBpNmQpWWwgoB9Hh8ubjiA5mnsd4m7irFv4TpVHQ/8tQpS5ulr6aE3L5w27JLeLgICSuGs0euXW1WMke7kYm1HQoT18r/J2wV0whDBvhM95Sq9if7jbY/QTIrHGludSKAFHaSYqzgwkgZMmaYU=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>OFX1IO/ASUF3c3wbfxNpJmBmBa9o9uiF4AH4M93MNbUCDf41GuvwhjfjDsBpKGKlk6PAapng2OFg7O9jpdBmT6Yxa27ga83CXEalcaXRb4rCzP9V9dlsx2DBXzFNcea6UqnAo3kbywkIojpvNrDKJQqSQbuLV+NzwVTufoRDVGYNABn/N+nwD/EIa2LmqyvZoOqEYPAUeao=</CipherValue>
      </CipherData>
    </EncryptedData>
  </appSettings>
<!-- 以下略 -->
```

###２．２．２．復号する場合

`Web.config`の設定値の確認や修正のために、暗号化済みの`Web.config`を復号する方法です。

```:復号
aspnet_regiis.exe -pdf <セクション名> <Web.configが格納されたフォルダのパス名>
```

* 暗号化時とのオプションの違いは、`-pef`が`-pdf`となっている点のみです。

#３．プログラムでの設定値の使用（C#）

暗号化された設定値をプログラムで使用する場合、復号は自動でやってくれますので、プログラマーは設定値を透過的に使用することが可能です。

```csharp:C#
using System.Configuration;

var result = ConfigurationManager.AppSettings["SecretKey"];
Console.WriteLine(result);  // p@5k#2Az
```

おめでとうございます。

#参考
[ASP.NET Web Configuration Guidelines](https://msdn.microsoft.com/en-us/library/ff400235(VS.100).aspx)