LoginSignup
10
9

More than 3 years have passed since last update.

.NET Core で秘密文字を安全に運用する(開発環境編)

Last updated at Posted at 2020-07-08

プログラムでの秘密の文字列

業務系のプログラムでは、何かしらのデータベースやストレージのシステムにアクセスし、データの入出力を行います。データベースなどへの接続の際には、アカウント/パスワードといった機密の文字列を使用することが多いと思いますが、これを開発段階からリリース、運用フェーズまで安全に管理するのは意外と大変です。

 プログラムから見た秘密の文字列の置き場所として、昔ながらの iniファイル、レジストリ、.NetFramework の場合は App.config に記述する方法などがありますが、基本的にプレーンテキストですので、扱いには気を使います。うっかりバージョン管理システムの管理対象にしてしまったり、デプロイ先で見つけられてしまうといったリスクがあります。ソースコードに直に埋め込んで、バイナリの中に隠すという方法も、実のところよく聞く話ですが、バイナリエディタで見れば、あっさりバレてしまいます。

 独自のハッシュ化やエンコード関数を自作されている話も聞きますが、他社との共同開発になった時、ライセンシーや、その関数のソースコードを他社と共有する点で課題が発生することになります。

Microsoft の秘密文字ソリューション

 秘密文字の管理のソリューションとして、Microsoft から2つの方法が提供されています。一つは、UserSecret を使う方法で、ローカルPC内の指定のディレクトリ内で管理します。管理場所が決まっていますので、うっかりバージョン管理システムにアップしてしまうこともありませんし、実装方法も簡単ですので、とっつきやすいと思います。ただ、暗号化などは行いませんので、Microsoft からは開発環境用としての位置づけとなっています。

もう一つは、Azure Key Vault を使う方法です。Azure Key Vault は、Microsoft のクラウド Azure のサービスの一つで、秘密の文字列をクラウドで管理します。Microsoft で厳重に管理されており、秘密文字へのアクセスには証明書が必要ですし、アクセスログも記録されます。エンタープライズ製品向けといえます。Microsoft では、UserSecret に比べ本番環境用として位置づけられています。

UserSecret を使った秘密文字の管理

 UserSecret 及び Azure Key Vault での実装方法などを見ていきたいと思います。サンプルプログラムでは、.Net Core のコンソールで行いますが、ASP.NET などでも考え方などは変わりません。

サンプルで使うもの等

  • Visual Studio Code
  • dotnet code 3.1
  • console プログラム
  • Windows/MacOS/Linux

プログラムの準備

dotnet コマンドで新規プロジェクトを作成します。ターミナルから次のコマンドを実行し、コンソールプログラムとして作成しています。

# mkdir vaultsample
# cd vaultsample
# dotnet new console

パッケージの追加とシークレットマネージャーの初期化

 UserSecrets に関連するパッケージをインストールします。.csproj ファイルがあるパスで次のコマンドを実行します。

# dotnet add package Microsoft.Extensions.Configuration
# dotnet add package Microsoft.Extensions.Configuration.UserSecrets

次に、シークレットマネージャーを初期化します。

# dotnet user-secrets init

インストールが完了すると、.csproj ファイルに Key Vault へのリファレンスが記述された ItemGroup と、追加されます。

ASP.NET Core の構成プロバイダーの Azure Key Vault
ASP.NET Core での開発におけるアプリシークレットの安全な保存

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UserSecretsId>07f81c45-c201-4de5-b9ff-96510163b7d6</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.5" />
  </ItemGroup>
</Project>

秘密文字の登録

次のコマンドで秘密文字を登録します。秘密文字は、シークレット名と値の組み合わせで登録します。

dotnet user-secrets set "SecretName" "secret_value_1_dev"
dotnet user-secrets set "Section:SecretName" "secret_value_2_dev"

なお、削除するときは次のようにコマンドを実行します。

dotnet user-secrets remove "SecretName" "secret_value_1_dev"

dotnet コマンドで作成しても構いませんが、格納先は下の通り、ユーザのホーム領域で、JSON 形式ですので、直接編集することもできます。

Windowsの場合
%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
Linux/MacOSの場合
~/.microsoft/usersecrets/<user_secrets_id>/secrets.json

また、Visual Studio Core の拡張ツール .NET Core User Secrets を使えば、UI 上で操作できます。

プログラムから秘密文字を取得する

 次に、登録した秘密文字列を、プログラムから取得する方法です。秘密文字などの管理には、ConfigurationBuilder を使用します。インスタンス化する際に、AddUserSecretsメソッドを呼び出すことで、UserSecret として登録した秘密文字を取得することができるようになります。

Program.cs
using System;
using Microsoft.Extensions.Configuration;

namespace vaultsample
{
  class Program
  {
    static void Main(string[] args)
    {
      var cbr = new ConfigurationBuilder()
      .AddUserSecrets<Program>().Build();

      Console.WriteLine($" secret key is {cbr["SecretName"]}");
    }
  }
}

これにより、

  • 秘密文字 -> ユーザのホームディレクトリ
  • 開発ソースコード -> 開発用ディレクトリ

という運用が可能になりました。

次の投稿で、Azure Key Vault を使用した、さらに安全性の高い秘密文字の運用方法を記載します。

(つづく)

<参考>

10
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9