March 2018
Volume 33 Number 3
Azure - Azure Key Vault を使って機微なビジネス情報のセキュリティを確保する
Azure Key Vault はクラウドベースのサービスで、組織がビジネスの機微な情報を安全に保存できるようにします。このサービスにより、データの暗号化操作を実行できます。さらに、アプリケーションへのアクセスを規制するポリシーを実装するためのフレームワークが提供されます。また、このサービスに保存したキー、シークレット、証明書を操作するアプリケーション用に API モデルも提供されます。Azure Key Vault が提供する SDK はさまざまなデバイス プラットフォームやプログラミング言語をサポートするため、好みの言語を選んで、アプリケーションをマネージ Web アプリケーションとして Azure App Service にデプロイできます。ビジネス アプリケーションを組織内外のユーザーに安全に公開するため、Azure Active Directory (Azure AD) と Azure Active Directory B2C (Azure AD B2C) によって簡単な実装が用意され、アプリケーションの認証と承認を最小限のコードまたはカスタム コードなしで実現できるようになります。ここでは、Azure Key Vault が組織のセキュリティを向上するしくみを示すソリューションについて説明します。
ユース ケース シナリオ
ある中央機関には、車両保険証券の発行、追跡、管理を行うソリューションを実装する役割があります。同機関は、保険会社からの発注と支払いの受領時に一意の文書シリアル番号を発行します。保険会社は、車両購入者への保険証券の販売時、保険証券にこの文書シリアル番号を直接またはブローカーを通じて割り当てます。文書シリアル番号は、すべての保険会社で一意になります。
このソリューションの目的は、文書シリアル番号のライフサイクルの追跡です。文書シリアル番号の発行時、そこにはその番号と、保険証券を販売した保険会社の名前しか含まれません。ビジネス プロセスが進むにつれ、車両登録、保険証券番号、顧客 ID、保険証券の有効期限などの追加情報が追加されていくことになります。追跡する必要があるのは、行われたすべての変更、変更日時、変更を行ったアプリケーションの ID を含め、この記録のすべてのバージョンです。
また、顧客が保険証券を検証したり、簡単に参照できるように、電子的なアクセスや情報のダウンロードを可能にすることも必要です。
ソリューションのアーキテクチャ
このソリューションでは、Azure Key Vault を使用して、文書シリアル番号とその関連保険証券のプロパティをシークレットとして格納します。セキュリティを強化するために、シークレットとして格納したデータは、Azure Key Vault で生成される非対称キーを使用して事前に暗号化されます。シークレットでキャプチャされる各証券のセキュリティの確保と検証には少量のデータが必要になりますが、こうした追加サポート情報は Azure SQL Database に格納します。データベースには制約も実装します。この制約によって、たとえば、登録車両に有効な証券番号が 1 つだけ割り当てられることや、複数のレコードに同一の証券番号が使用されないことなどを保証します。図 1 にこのソリューションのアーキテクチャを示します。
図 1 ソリューションのアーキテクチャ
このソリューションには 2 つのポータル アプリケーションを実装しています。1 つは、中央機関と保険会社が使用するポータル、もう 1 つは保険証券を購入した顧客や証券の有効性を確認する規制当局が使用するポータルです。
前者を管理者ポータル、後者を顧客ポータルと呼びます。これらのポータルは、ASP.NET 2.0 Core MVC アプリケーションです。このアプリケーションは、証券データを Azure Key Vault に最初に格納後、Entity Framework を使用してそのデータを Azure SQL Database に格納します。Azure Key Vault 向け .NET SDK は、シークレットやシークレットのバージョンの作成、キーを使ったシークレットの暗号化や暗号化解読など、データの暗号操作を実行するために使用します。管理者ポータルのユーザーは Azure AD で認証を受けます。一方、社外ユーザーである顧客は Azure AD B2C を使用して顧客ポータルに自己登録して、サインインします。
管理者ポータル用と顧客ポータル用に、Azure AD に個別のサービス プリンシパルを作成し、Azure Key Vault の操作へのアクセスを制御する個別のポリシーを設定します。管理者ポータルのポリシーは、キーとシークレットの作成、データの暗号化と暗号化解除などの操作の実行を許可します。一方、顧客ポータルには、シークレットに対する "get" 操作と、取得したシークレットに対する "decrypt" 操作のみを許可するポリシーが割り当てられます。これにより、個々のアプリケーションが必要以上に Azure Key Vault にアクセスしないようにします。
Azure Key Vault にシークレットとして格納される証券データは、セキュリティ強化のために最初に暗号化されます。シークレットは、更新のたびに新しいバージョンが作成され、前回バージョンのデータが保持されます。Key Vault で実行されるすべての操作の監査記録が管理されます。この記録は、法令準拠要件を満たすためアーカイブされます。
Azure Key Vault に格納されるシークレットの一連の属性は、証券の開始日と終了日をキャプチャします。これらは、証券の有効性の確認に使用されます。シークレットのタグと content-type パラメーターは、保険証券に関する追加情報の格納に使用されます。
以下のコード スニペットは、属性、タグ、およびコンテンツ タイプをシークレットとして証券データに追加する方法を示しています。
SecretAttributes attribs = new SecretAttributes
{
Enabled = true,
Expires = DateTime.UtcNow.AddYears(1),
NotBefore = DateTime.UtcNow.AddDays(1)
};
IDictionary<string, string> alltags = new Dictionary<string, string>();
alltags.Add("InsuranceCompany", policydata.Inscompany);
string contentType = "DigitalInsurance";
SecretBundle bundle= await _keyVaultClient.SetSecretAsync(keyVaultUri,
policydata.Uidname,encrypteddata,alltags,contentType,attribs);
ユース ケース シナリオの実装
このソリューションで実装するユース ケース シナリオについて詳しく見ていくことにします。以下に基本的な手順を示します。
保険会社による一意コードの購入: 中央機関は保険会社から注文を受領すると、管理者ポータルを使用して文書シリアル番号のインベントリを生成し、シークレットとして Azure Key Vault に格納します。管理者ポータルはシークレットの最初のバージョンを Azure Key Vault に作成してから、Azure SQL Database にレコードを作成します。
証券の生成: 顧客が車両保険を購入したら、前の手順で作成した中から未割り当てのシークレットを選択し、車両登録番号、顧客 ID、生成された証券文書番号、証券の有効期間などの情報を追加します。このプロセスではオリジナルのシークレットにこれらの追加情報を含めた新しいバージョンを作成し、Azure SQL Database の対応レコードも更新します。
顧客による証券の登録: 証券のすべての詳細をシークレットに取り込んだら、証券を登録する手順を含む通知を顧客に送信します (これについては今回の範囲を超えるため説明は省略します)。ユーザーはソーシャルの資格情報または Azure AD B2C に格納している資格情報を使用して、顧客ポータルで自己登録できます。顧客がポータルにサインインすると、証券の詳細と、証券の登録オプションを表示します。登録時、顧客はポータルから QR コードをダウンロードして、その画像を被保険車両に貼ります。
証券の検証: 顧客や規制当局は、Xamarin アプリケーションを使用していつでも車両に貼られた QR コードを読み取って証券の詳細を表示し、車両の証券と照合できます。この検証はインターネットに接続する必要はなく、オフラインで実行できます。インターネットに接続すると、追加の検証も実行できます。ネイティブ Xamarin アプリケーションは顧客ポータルの MVC アプリケーションで公開されている REST API を呼び出し、QR コードのデータを渡します。API は最初にこのデータを Azure SQL Database のデータと照合し、次に Azure Key Vault に格納されたデータと照合します。
ソリューションの技術面
ここからは、このソリューションで使用するソース コードと自動スクリプトを詳しく見ていきます。ここで扱うコードとスクリプトは、完全なソリューションを意図したものではなく、運用アプリケーションに必要な検証、例外、またはベスト プラクティスには完全には対応していません。どちらかと言えば、テクノロジ分野の特定の側面を説明し、本格的なソリューションを開発するためのガイダンスを提供することを目的としています。
Azure Key Vault の作成と構成: 本稿付属のコード ダウンロードに含まれる PrepareContosoAKV.ps1 と PrepareContosousersAKV.ps1 という PowerShell スクリプト ファイルを使って、ここで使用するキー コンテナーのプロビジョニングと構成を行います。それぞれのファイルの役割は以下のとおりです。
- 管理者ポータルと顧客ポータルの ASP.NET MVC アプリケーション用の自己署名証明書 (開発シナリオでのみ使用) の作成。この証明書は、Azure AD でのサービス プリンシパルの作成に使用します。
- 管理者ポータルに割り当てる Azure AD のサービス プリンシパルの作成。このサービス プリンシパルに設定されるアクセス ポリシーは、キーとシークレットの作成と更新、暗号化や暗号化解除などの操作の実行を許可します。
# Specify privileges to the vault for the Admin Portal application
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName `
-ObjectId $servicePrincipal.Id `
-PermissionsToKeys all `
-PermissionsToSecrets all
- 顧客ポータルに割り当てるサービス プリンシパルの Azure AD での作成。このサービス プリンシパルに設定されるアクセス ポリシーは、キーとシークレットの取得 (Get) 操作とデータの暗号化解除を許可します。
# Specify privileges to the vault for the Customer Portal application
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName `
-ObjectId $servicePrincipal.Id `
-PermissionsToKeys get,list,decrypt `
-PermissionsToSecrets get,list
- これらのサービス プリンシパルの作成には、PowerShell を使用する代わりに、Azure App Service の「管理対象のサービス ID 」機能を使用する方法もあります。実際のところ、こちらの方法がお勧めです。詳細については、bit.ly/2BgB6mu のガイダンスを参照してください。
- シークレットの暗号化と暗号化解除に使用するキーの作成。
- Azure SQL Database への接続文字列を格納するシークレットの作成 (他の手順と同様、Azure Portal で直接行うことも可能です)。
説明を簡潔にするため、このソリューションでは、すべての保険会社とブローカーが単一のキー コンテナー、単一のキーセットを使用してデータの暗号化と暗号化解除を行います。実際の環境では、分離性とセキュリティの強化のため、保険会社ごとに個別の Azure Key Vault インスタンスを作成し、地域やその他の条件でグループ化します。これにより、同じ暗号化キーが共有されなくなるため、ある保険会社が管理するデータに別の会社がアクセスすることはできなくなります。
Azure Key Vault に格納されるシークレットのサイズは、25KB を超えてはなりません。そのため、データの増大を避けるために、ID (文書シリアル番号)、シークレット名、ユーザーID、証券番号、保険会社 ID といった一定のプロパティだけを Azure Key Vault に格納します。Visual Studio 2017 ソリューション (ContosoInsAuthorityAdminPortal.sln) の Entity Insdata.cs ファイルがこれらのプロパティを保持します。有効な開始日と終了日、コンテンツ タイプなど、その他のプロパティはシークレットの属性としてキー コンテナーに格納します。
管理者ポータルと顧客ポータルのアプリケーションのビルド: 管理者ポータルのソース コードについては本稿付属のダウンロードに含まれる Visual Studio 2017 ソリューション (ContosoInsAuthorityAdminPortal.sln) を参照してください。顧客ポータルのソース コードについては ContosoinsExtPortal.sln を参照してください。
管理者ポータルと顧客ポータルはどちらも ASP.NET Core 2.0 を使用してビルドします。ASP.NET Core 2.0 は、スタートアップ クラスでアプリケーションにフレームワーク サービスを追加するために依存関係の注入をサポートします。こうしたフレームワーク サービスには、Entity Framework 統合や、Azure Key Vault API にアクセスするためのカスタム サービス モジュールなどがあります。
Visual Studio 2017 プロジェクト テンプレートは、ユーザーのサインインとサインアップのエクスペリエンス向けに、Azure AD と Azure AD B2C との簡単な統合を提供し、ポータル アプリケーションへの安全なアクセスを可能にします。
Azure SQL Database の接続文字列は Azure Key Vault に格納し、ポータル Web アプリケーションの起動時に取得されます。
図 2 のコード スニペットは、Entity Framework Azure AD 認証とアクセス プロバイダー (Azure Key Vault Service API) アクセス向けに ASP.NET 2.0 Core の依存関係の注入を 追加し、appsettings.json ファイルのアプリケーション構成データを読み取る方法を示しています。
図 2 ASP.NET Core 2.0 MVC アプリケーションの依存関係フレームワーク
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Adding the Azure AD integration for User authentication
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.AddMvc();
// Add the Key Vault Service Client Connection to the Context Object
AKVServiceClient servClient =
new AKVServiceClient(Configuration["AzureKeyVault:ClientIdWeb"],
Configuration["AzureKeyVault:AuthCertThumbprint"],
Configuration["AzureKeyVault:VaultName"],
Configuration["AzureKeyVault:KeyName"]);
services.AddSingleton<AKVServiceClient>(servClient);
// Get the Connection string to Azure SQL Database
// from the secret in Azure Key Vault
string connection = servClient.GetDbConnectionString();
// Add the Azure SQL Database Connection to the Context Object
services.AddDbContext<ContosoinsauthdbContext>(options =>
options.UseSqlServer(connection));
services.AddOptions();
}
NuGet パッケージとして利用可能な ASP.NET Core 2.0 の Azure Key Vault 構成プロバイダー (bit.ly/2DfOXeq) は、アプリケーションの起動時に Azure Key Vault からすべてのシークレットを取得するための簡単な実装を提供します。しかし、この機能は今回のソリューションでは使用しません。それは、アプリケーションの起動時に不要なビジネス データをすべて読み込まないようにするためです。たとえば、保険証券シークレットや、Azure SQL Database にアクセスするための接続文字列などのアプリケーションが必要とするその他のシークレットは起動時に読み込む必要はありません。この機能は、アプリケーションに必要なすべての接続文字列の格納に 1 つのキー コンテナー インスタンスを使用し、ビジネス データに別のキー コンテナー インスタンスを使用する場合に利用できます。
App Service の作成: 管理者ポータルと顧客ポータルのアプリケーションは、Visual Studio 2017 の組み込みツールを使用して Azure App Service Web アプリケーションとしてデプロイします。どちらのポータルも、1 つの App Service プランの内部でホストされます。
開発中は、Visual Studio 2017 を使用して ASP.NET Core MVC アプリケーションをローカルにデプロイできます。先ほど説明した PowerShell スクリプトを実行すると、ポータル アプリケーションごとに 1 つずつ、合計 2 つのデジタル証明書が作成されます。現在のユーザーの証明書ストアに .pfx ファイルが追加されます。このファイルは、ASP.NET MVC アプリケーションが Azure Key Vault API にアクセスするために行う要求に埋め込みます。各 ASP.NET MVC アプリケーションの Visual Studio 2017 ソリューションの appsettings.json ファイルに、これらの証明書の拇印を追加します。
アプリケーションを Azure App Service にデプロイするときは、以下のことを行う必要があります。
- 両方の .pfx ファイルを Azure Portal から Azure App Service インスタンスにアップロードする。
- Azure Portal で管理者ポータルと顧客ポータルの Web アプリケーションの [App Settings] (アプリの設定) ブレードに "WEBSITE_LOAD_CERTIFICATES" エントリを追加し、それぞれの .pfx ファイルの拇印を追加する。
実行する手順の詳細については、bit.ly/2mVEKOq のドキュメントを参照してください。
データべースの作成: ソリューションのデータベース作成に使用したスクリプト ファイルは、このソリューションの他のアーティファクトとともにダウンロードできます。データベースで Transparent data encryption (TDE) と監査を有効にします。
Azure AD と Azure AD B2C テナントの作成: Azure サブスクリプションの既定の Azure AD テナントは、管理者ポータルにアクセスする中央機関の社内ユーザーの ID プロバイダーとして使用します。このサブスクリプションに別の Azure AD テナントを作成し、保険会社を表すユーザーを登録します。これらのユーザーは、ポータル アプリケーションにアクセスできるように、ゲスト ユーザーとして既定の Azure AD テナントに追加します。保険会社に独自の Azure AD テナントがある場合、Azure AD B2B を使用してそのテナントをこのサブスクリプションの既定の Azure AD テナントと連携させることができます。
Azure Portal で Azure サブスクリプションに Azure AD B2C テナントを作成し、顧客がセルフサインアップしてポータルにアクセスできるようにポリシーを定義します。Azure AD B2C 構成の ID プロバイダーのセクションでは、このテナントのローカル アカウントを電子メール アドレスではなく、"user name" に設定しています。これは、説明が簡単になるように、ユーザーサインアップ時の電子メール検証を無効にするためです。サインインとサインアップのエクスペリエンス向けのポリシーの作成と構成についてのガイダンスは、Azure AD B2C のドキュメント (bit.ly/2n7Vro9) を参照してください。
アプリケーションの実行
読者がこのソリューションを実行できるようにサンプルの資格情報を用意しています。これを使用して、本稿関連の GitHub リポジトリの管理者ポータルと顧客ポータルにサインインできます。
今回のソリューションの説明を簡単にするため、保険会社が一意のコードを購入する手順は実装していません。代わりに、管理者ポータルのユーザーは、文書シリアル番号、顧客情報、証券および車両の詳細情報がすべて 1 度に取り込む手順を直接実行することになります。
図 3 に、管理者ポータル Contoso Insurance の開始ページを示します。保険会社ユーザーの資格情報を使用して管理者ポータルにサインインし、[Create New] (新規作成) を選択して新しいドキュメントの詳細を入力します。文書シリアル番号がアプリケーションによって自動作成され、[New] (新規) または [Edit Item Form] (アイテムを編集するフォーム) にのみ表示されます。
図 3 Contoso Insurance 管理者ポータルの開始ページに表示される保険証券一覧
図 4 に、シークレットとして格納される証券データの別のバージョンを示します。コンテンツ タイプ、タグ、属性などの追加情報も表示できます。シークレットを格納する前に暗号化しています。
図 4 シーレットとして格納される保険証券データの複数のバージョンの Azure Portal 表示
顧客ポータルにサインインすると、購入済みで登録可能な状態の保険証券をすべて確認できます。証券の編集ページには証券を登録するオプションがあります。そこで Azure SQL Database の証券の状態を [Active] (登録) に更新します。証券を登録したら、[Download Policy] (ポリシーのダウンロード) オプションを利用して証券データの QR コードを作成できます。
図 5 に QR コードをダウンロードする際の顧客ポータルのユーザー エクスペリエンスを示します。モバイル デバイスのアプリケーションを使用して QR コードから読み取られた JSON データも表示します。ネイティブ アプリケーションは QR コードをスキャンして、オフラインでも簡単に検証を行えるように画面上に書式を設定した証券の詳細を表示します。
図 5 QR コードの作成
Azure Key Vault の秘密キーを使用して顧客ポータルで JSON に署名し、署名済みデータの QR コードを生成することで、セキュリティを強化できます。検証の場合は、JSON データをモバイル デバイスに表示する前に、署名済みデータの検証に必要な秘密キーと共にネイティブ モバイル アプリケーションをリリースできます。
顧客ポータルでは、GitHub (bit.ly/2sa3TWy) からダウンロードできる JavaScript 用の QR コード ジェネレーターを使用して QR コードを生成および表示します。
証券の検証
証券はオフラインでもオンラインでも検証できます。オフラインでの検証は、モバイル デバイスの任意の QR コード リーダー アプリケーションまたはネイティブの Xamarin アプリケーションを使用して実行できます。QR コードのスキャンが完了したら、結果が検証のためにユーザーにわかりやすいように表示されます。
一方、 図 6 には、Postman ツール (getpostman.com) を使用して MVC アプリケーションの API に送信された検証の要求が表示されています。検証の結果はブール型で返されます。この場合、証券の開始日が現在日よりも後のため、検証の結果は "false" です。 Xamarin アプリケーションを使用して、ユーザーがサインインし、QR コードをスキャンして表示し、この API にオンラインでの検証を行うように要求することができます。
図 6 証券を検証するための REST API 呼び出し
Azure Key Vault でのすべての操作は監査可能で、法令規則への準拠のため、ログはアーカイブされます。Azure Portal の Azure Key Vault サービス インスタンスの [設定] ブレードから、監査を有効にします。ログを表示するには、ログ用に構成された Azure ストレージ リソースに移動します。Azure Portal で役割ベースのアクセス制御 (RBAC) を使用して、指定されたユーザーだけがこの情報にアクセスできるようにします。
Azure SQL Database のデータへのすべての操作に対しても、Azure Portal の Azure SQL Database インスタンスの [設定] ブレードから監査を有効にできます。Azure SQL Database に格納されているデータの自動的な暗号化は既定で有効になっています。
ソリューションのデプロイ
GitHub リポジトリ (bit.ly/2DRvwdh) からソース ファイルとスクリプトをダウンロードして、このソリューションを実際に試すことができます。このソリューションを実装するには、以下のソフトウェアが必要です。
- Visual Studio 2017 Update 3 の Preview、Community、または Enterprise Edition
- Azure サブスクリプション
- Windows PowerShell スクリプト エディター
- Postman
- JavaScript 用の QR コード ジェネレーター
ソリューションを独自のサブスクリプションにデプロイするには、PowerShell スクリプトを実行し、Azure サブスクリプションで他のリソースがプロビジョニングされた後に appsettings.json の config エントリを更新する必要があります。更新の手順は、本稿で説明したソース コードとソリューション ファイルとともに GitHub リポジトリで提供しています。本稿付属のソリューションのビルドにご協力いただいた Microsoft CSE チームの Bindu Chinnasamy に感謝します。
まとめ
Azure Key Vault は、暗号化操作の実行に業界標準のアルゴリズムとテクノロジーを使用することで、安全に機密情報を管理できる便利で効率的なプラットフォームを企業に提供します。開発者は、使い慣れたプラットフォームと言語の SDK を使用できます。これに加え、Azure App Service や Azure AD、Azure B2C といった Azure の豊富なサービス、およびこれらのサービスが提供するツールの入念なサポートにより、開発者は中核となるビジネス機能に専念できます。そのため、エンドツーエンドのソリューションの開発とデプロイにかかる時間が大幅に短縮されます。
次回以降は、大きな変更を加えることなく、同じアプリケーションを Docker コンテナーと Kubernetes を使用して Azure Container Service にデプロイする方法を説明します。
Srikantan Sankaran は、インドのバンガロールを拠点に各地で活動する One Commercial Partner チームのプリンシパル テクニカル エバンジェリストです。彼は、インドのさまざまな独立系ソフトウェア ベンダー (ISV) と共に活動しており、Microsoft Azure にソリューションをデプロイしています。連絡先は sansri@microsoft.com (英語のみ) です。
この記事のレビューに協力してくれたマイクロソフト技術スタッフの Frank Hokhold、Bindu Chinnasamy に心より感謝いたします。
この記事のレビューに協力してくれた Frank Hokhold に感謝します。Frank は Azure Key Vault チームで Developer Experience プログラム マネージャーを務めています。
また、本稿付属のソリューションの構築にご協力いただいた Microsoft CSE チームの Bindu Chinnasamy に感謝します。