「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。
-[[戻る>Microsoft Passport]]
* 目次 [#x5106216]
#contents
*概要 [#f8516d04]
-[[Microsoft Passport]]が提供するプログラミングシステムのAPI
-Windowsデバイス上で、[[FIDO]]を実装する場合に、このAPIを利用する。
*クライアント実装 [#r4886e70]
**共通 [#s0d4b169]
-アプリケーションに登録開始リクエストを送る。
-challenge、policy、appIDなどが返される。
***policyに適合する認証器を調べる [#d4ce3298]
***認証器の調査: KeyCredentialManager.IsSupportedAsync()メソッド [#jdffe4a8]
-ユーザーが Windows Hello をセットアップしたかどうかを調べる
if (await KeyCredentialManager.IsSupportedAsync() == false)
{
・・・
***キーのストア&コンテナを開く: KeyCredentialManager.OpenAsync()メソッド [#o536dd3d]
当該ユーザ&アプリケーションのキーのストア&コンテナを開く。
// retrieve private key for sign
KeyCredentialRetrievalResult res =
await KeyCredentialManager.OpenAsync("keyName");
**登録 [#mf95bb5b]
-[[上記のKeyCredentialManager.OpenAsync>#o536dd3d]]の結果が、
if (res.Status == KeyCredentialStatus.NotFound)
{
・・・
>の場合、
-≒新規のdeviceを登録する場合、若しくは、追加のデバイスを登録する場合。
***キーペアを作成する: KeyCredentialManager.RequestCreateAsync()メソッド [#x9609a48]
-RequestCreateAsyncを使用してキーペアを作成する。
--Windows Helloに対応した認証器に生体認証の情報を入力する。
--入力後、内部では、private key と public key が作成される。
--private key は TPM に登録され、以降、認証器によって保護される。
--private key は [[TPM>TPM(Trusted Platform Module)]] に登録され、以降、認証器によって保護される。
-実装
// Create the credential
// (Windows Hello is diplayed here !)
KeyCredentialRetrievalResult createRes =
await KeyCredentialManager.RequestCreateAsync("keyName", KeyCredentialCreationOption.ReplaceExisting);
// if the status is success, retrieve the public key.
if (createRes.Status == KeyCredentialStatus.Success)
{
・・・public keyとattestationを取得する。
}
else if(
keyCreationResult.Status == KeyCredentialStatus.UserCanceled ||
keyCreationResult.Status == KeyCredentialStatus.UserPrefersPassword)
{
// Show error message to the user to get confirmation that user does not want to enroll.
}
***public keyを取得する: KeyCredential.RetrievePublicKey()メソッド [#pd6ccca1]
-public keyを取得する。
-実装
KeyCredential userKey = keyCreationResult.Credential;
IBuffer publicKey = userKey.RetrievePublicKey();
***attestationを取得する: KeyCredential.GetAttestationAsync()メソッド [#j562a388]
-attestation(デバイス正常性構成証明)を取得する。
-実装
KeyCredentialAttestationResult keyAttestationResult = await userKey.GetAttestationAsync();
IBuffer keyAttestation = null;
IBuffer certificateChain = null;
bool keyAttestationIncluded = false;
bool keyAttestationCanBeRetrievedLater = false;
KeyCredentialAttestationStatus keyAttestationRetryType = 0;
if (keyAttestationResult.Status == KeyCredentialAttestationStatus.Success)
{
keyAttestationIncluded = true;
keyAttestation = keyAttestationResult.AttestationBuffer;
certificateChain = keyAttestationResult.CertificateChainBuffer;
rootPage.NotifyUser("Successfully made key and attestation", NotifyType.StatusMessage);
}
else if (keyAttestationResult.Status == KeyCredentialAttestationStatus.TemporaryFailure)
{
keyAttestationRetryType = KeyCredentialAttestationStatus.TemporaryFailure;
keyAttestationCanBeRetrievedLater = true;
rootPage.NotifyUser("Successfully made key but not attestation", NotifyType.StatusMessage);
}
else if (keyAttestationResult.Status == KeyCredentialAttestationStatus.NotSupported)
{
keyAttestationRetryType = KeyCredentialAttestationStatus.NotSupported;
keyAttestationCanBeRetrievedLater = false;
rootPage.NotifyUser("Key created, but key attestation not supported", NotifyType.StatusMessage);
}
***上記の情報をサーバに飛ばして登録する。 [#mb7ccf4d]
-PublicKey
IBuffer publicKey
-KeyAttesation
IBuffer keyAttestation
--certificate chain for attestation endorsement key
IBuffer certificateChain
--status code of key attestation result
bool keyAttestationIncluded
bool keyAttestationCanBeRetrievedLater
KeyCredentialAttestationStatus keyAttestationRetryType
-実装
// Package public key, keyAttesation if available,
// certificate chain for attestation endorsement key if available,
// status code of key attestation result: keyAttestationIncluded or
// keyAttestationCanBeRetrievedLater and keyAttestationRetryType
// and send it to application server to register the user.
bool serverAddedPassportToAccount = await AddPassportToAccountOnServer();
if (serverAddedPassportToAccount == true)
{
return true;
}
-サーバ側~
[[こちら>#h5e2d6ee]]。
**認証 [#m53e84af]
[[上記のKeyCredentialManager.OpenAsync>#o536dd3d]]の結果が、
if (res.Status == KeyCredentialStatus.Success)
{
・・・
の場合、
***KeyCredentialManager.RequestSignAsync()メソッド [#x249d76f]
[[登録>#h5b260df]]後、PIN や 生体認証を使って、challengeにデジタル署名 (RequestSignAsync) する。
var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);
if (openKeyResult.Status == KeyCredentialStatus.Success)
{
var userKey = openKeyResult.Credential;
var publicKey = userKey.RetrievePublicKey();
var signResult = await userKey.RequestSignAsync(message);
if (signResult.Status == KeyCredentialStatus.Success)
{
return signResult.Result;
}
else if (signResult.Status == KeyCredentialStatus.UserPrefersPassword)
{
}
}
***上記の情報をサーバに飛ばして認証する。 [#d9e101a4]
[[こちら>#m586e835]]
**その他 [#l36fc4ff]
***UserConsentVerifier.RequestVerificationAsync()メソッド [#x8f6e46c]
ある特定の箇所で 生体認証を呼び出してOKかNOか確認したい場合
if (await UserConsentVerifier.CheckAvailabilityAsync() ==
UserConsentVerifierAvailability.Available)
{
UserConsentVerificationResult res =
await UserConsentVerifier.RequestVerificationAsync(
"This is sensitive operation ! Please authenticate again.");
if(res == UserConsentVerificationResult.Verified)
{
// some important action …
}
}
***KeyCredentialManager.DeleteAsync()メソッド [#a88cf643]
private keyを削除する。
await KeyCredentialManager.DeleteAsync("keyName");
*サーバ実装 [#d263bb7b]
**サンプルのデータベース スキーマ [#da11a4e9]
***User [#s3fe73af]
-id
-e-mail address
-first name
-last name
***UserKeys [#j15d23ad]
-id
-user id
-public key
-attestation
-device id
-last logontime
**処理 [#n8303bac]
***登録 [#h5e2d6ee]
UserKeysレコードを追加。
***認証 [#m586e835]
using (RSACng pubKey = new RSACng(publicKey))
{
retval = pubKey.VerifyData(
originalChallenge, responseSignature,
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
*参考 [#r42666b1]
-Windows Hello を使った App 開発 – Tsmatz~
https://blogs.msdn.microsoft.com/tsmatsuz/2015/07/30/windows-hello-app/
**docs.microsoft.com [#s410a0be]
-UWP app developer
--Windows Hello~
https://docs.microsoft.com/ja-jp/windows/uwp/security/microsoft-passport
---Windows Hello ログイン アプリの作成~
https://docs.microsoft.com/ja-jp/windows/uwp/security/microsoft-passport-login
---Windows Hello ログイン サービスの作成~
https://docs.microsoft.com/ja-jp/windows/uwp/security/microsoft-passport-login-auth-service
--(Windows.Security.Credentials)
---KeyCredential Class (Windows.Security.Credentials)~
https://docs.microsoft.com/en-us/uwp/api/windows.security.credentials.keycredential
---KeyCredentialManager Class (Windows.Security.Credentials)~
https://docs.microsoft.com/en-us/uwp/api/windows.security.credentials.keycredentialmanager
---KeyCredentialAttestationResult Class (Windows.Security.Credentials)~
https://docs.microsoft.com/en-us/uwp/api/windows.security.credentials.keycredentialattestationresult
**Microsoft/Windows-universal-samples [#u118327d]
-MicrosoftPassport~
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/MicrosoftPassport
--クライアント(UWP)~
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/MicrosoftPassport/cs
--サーバ(ASP.NET MVC)~
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/MicrosoftPassport/Server
----
Tags: [[:Windows]], [[:認証基盤]]