Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

Azure KeyVaultを使ったClient Side Encryption

前回は、Azure Key Vaultのライブラリのみを使いましたが、今回はシークレットをAzure Key Vaultに格納してそれを利用してみたいと思います。

Azure KeyValutは、シークレットや証明書などを保管するサービスでAAD(Windows Azure Active Directory)と連携してそれらを使えます。概要などは、以下のURLをさらっとあたってください。

channel9.msdn.com

azure.microsoft.com

おおざっぱな概念図は、以下の通りです。管理は、PowerShellもしくはREST APIで行い、アプリからはAADで認証後、情報をとりだします。

f:id:StateMachine:20150712112850p:plain

パッケージ

前回と同じパッケージに加えて、AADのライブラリが必要です。

Install-Package WindowsAzure.Storage -Pre
Install-Package Microsoft.Azure.KeyVault
Install-Package Microsoft.Azure.KeyVault.Extensions -Pre
Install-Package Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

リソースの作成

Azure KeyValutは、現状Azure PowerShellのARMモードでのみ管理が可能です。Switch-AzureModeコマンドでARMモードに切り替えたら、

  • リソースグループ
  • ストレージアカウント
  • KeyVakut

を作成します。

Switch-AzureMode -Name AzureResourceManager
New-AzureResourceGroup -Name testrg -Location japanwest
New-AzureStorageAccount -ResourceGroupName testrg -Location japanwest -Name bobobo339 -Type Standard_LRS
New-AzureKeyVault -ResourceGroupName testrg -VaultName bobobo339kv -Location japanwest

AADの設定

AADのディレクトリにアプリケーションを登録します。アプリケーションの追加するとウィザード画面になるので、

  1. 組織で開発中のアプリケーションを追加
  2. WEBアプリケーションやWEB APIを選択
  3. サインオンURLとアプリケーションIDは適当

に設定するとアプリが追加されます。アプリの構成画面から、クライアントIDとキーを確認しておきます。

f:id:StateMachine:20150712122939p:plain

Key Valutの設定

AADからクライアントIDをコピーしておきます。Set-AzureKeyVaultAccessPolicy コマンドで先程作成したクライアントからのアクセスポリシーを設定します。パーミッションをall/delete/get/list/set で設定できます。

$clientId = "XXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX"
Set-AzureKeyVaultAccessPolicy -ResourceGroupName testrg -VaultName bobobo339kv `
     -PermissionsToKeys all -PermissionsToSecrets all `
     -ServicePrincipalName $clientId

次にキー登録ですが、ごにょごにょとやっていますが、128bitのキーをシークレットとして登録しています。

# 16 char * 8  = 128 bits
$key = "fjekbgjsjfef3ks0"
$b = [System.Text.Encoding]::UTF8.GetBytes($key)
$enc = [System.Convert]::ToBase64String($b)
$secretvalue = ConvertTo-SecureString $enc -AsPlainText -Force

## substitute the VaultName and Name in this command
$secret = Set-AzureKeyVaultSecret -VaultName bobobo339kv `
 -Name 'TestSecret' -SecretValue $secretvalue `
 -ContentType "application/octet-stream"

キーの取得

キー取得は、AADで認証したのちに、KeyValutのライブラリで取得します。GetAccessTokenはAADで認証し、KevValutへアクセスするためのTokenを取得します。あとは、KeyVaultKeyResolver 経由で取得できます。

以下コード中の変数は以下のように設定しておきます。

  • clinetId は、 AADのクライアントID
  • clientKey は、 AADの認証キー
  • valutUrl は、 https://bobobo339kv.vault.azure.net:443/secrets/TestSecret など
static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
    ClientCredential credential = new ClientCredential(clientId, clientKey);
    AuthenticationContext ctx = new AuthenticationContext(new Uri(authority).AbsoluteUri, false);
    AuthenticationResult result = await ctx.AcquireTokenAsync(resource, credential);
    return result.AccessToken;
}

static IKey GetKey()
{
    var cloudResolver = new KeyVaultKeyResolver(GetAccessToken);
    var key = cloudResolver.ResolveKeyAsync(vaultUrl, CancellationToken.None).GetAwaiter().GetResult();
    return key;
}

リゾルバーには、AggregateKeyResolver クラスのようにいくつかのResolverを集約したり、CachingKeyResolver クラスのようにキャッシュしてくれるラッパーがあります。CachingKeyResolver は普通に使った方が良いと思います。

キーが取得できれば前回と同様ですので、これにておしまい。