スマート カードSmart cards

このトピックでは、ユニバーサル Windows プラットフォーム (UWP) アプリでスマート カードを使ってユーザーをセキュリティで保護されたネットワーク サービスに接続する方法のほか、物理スマート カード リーダーにアクセスする方法、仮想スマート カードの作成方法、スマート カードとの通信方法、ユーザーの認証方法、ユーザーの PIN のリセット方法、スマート カードの取り外しや切断の方法などについて説明します。This topic explains how Universal Windows Platform (UWP) apps can use smart cards to connect users to secure network services, including how to access physical smart card readers, create virtual smart cards, communicate with smart cards, authenticate users, reset user PINs, and remove or disconnect smart cards.

アプリ マニフェストの構成Configure the app manifest

アプリでスマート カードや仮想スマート カードを使ってユーザーを認証するには、あらかじめプロジェクトの Package.appxmanifest ファイルで、共有ユーザー証明書機能を設定しておく必要があります。Before your app can authenticate users using smart cards or virtual smart cards, you must set the Shared User Certificates capability in the project Package.appxmanifest file.

接続されているカード リーダーとスマート カードへのアクセスAccess connected card readers and smart cards

DeviceInformation に指定されているデバイス ID を SmartCardReader.FromIdAsync メソッドに渡すと、リーダーや装着されているスマート カードを照会することができます。You can query for readers and attached smart cards by passing the device ID (specified in DeviceInformation) to the SmartCardReader.FromIdAsync method. 返されたリーダー デバイスに現在装着されているスマート カードにアクセスするには、SmartCardReader.FindAllCardsAsync を呼び出します。To access the smart cards currently attached to the returned reader device, call SmartCardReader.FindAllCardsAsync.

string selector = SmartCardReader.GetDeviceSelector();
DeviceInformationCollection devices =
    await DeviceInformation.FindAllAsync(selector);

foreach (DeviceInformation device in devices)
{
    SmartCardReader reader =
        await SmartCardReader.FromIdAsync(device.Id);

    // For each reader, we want to find all the cards associated
    // with it.  Then we will create a SmartCardListItem for
    // each (reader, card) pair.
    IReadOnlyList<SmartCard> cards =
        await reader.FindAllCardsAsync();
}

また、カードが挿入されたときのアプリの動作を処理するメソッドを実装して、アプリによる CardAdded イベントの監視を有効にする必要もあります。You should also enable your app to observe for CardAdded events by implementing a method to handle app behavior on card insertion.

private void reader_CardAdded(SmartCardReader sender, CardAddedEventArgs args)
{
  // A card has been inserted into the sender SmartCardReader.
}

その後、返された各 SmartCard オブジェクトを SmartCardProvisioning に渡すことで、その構成へのアクセスやカスタマイズを行うメソッドを使えるようになります。You can then pass each returned SmartCard object to SmartCardProvisioning to access the methods that allow your app to access and customize its configuration.

仮想スマート カードの作成Create a virtual smart card

アプリで SmartCardProvisioning を使って仮想スマート カードを作成するには、まずフレンドリ名、管理者キー、SmartCardPinPolicy を提供する必要があります。To create a virtual smart card using SmartCardProvisioning, your app will first need to provide a friendly name, an admin key, and a SmartCardPinPolicy. 通常、フレンドリ名は既にアプリに用意されている可能性がありますが、アプリではさらに、管理者キーを提供し、現在の SmartCardPinPolicy のインスタンスを生成する必要があります。その後、これらの 3 つの値をすべて RequestVirtualSmartCardCreationAsync に渡します。The friendly name is generally something provided to the app, but your app will still need to provide an admin key and generate an instance of the current SmartCardPinPolicy before passing all three values to RequestVirtualSmartCardCreationAsync.

  1. SmartCardPinPolicy の新しいインスタンスを作成します。Create a new instance of a SmartCardPinPolicy
  2. サービスまたは管理ツールから提供された管理者キーの値に対して CryptographicBuffer.GenerateRandom を呼び出して、管理者キーの値を生成します。Generate the admin key value by calling CryptographicBuffer.GenerateRandom on the admin key value provided by the service or management tool.
  3. これらの値と FriendlyNameText 文字列を RequestVirtualSmartCardCreationAsync に渡します。Pass these values along with the FriendlyNameText string to RequestVirtualSmartCardCreationAsync.
SmartCardPinPolicy pinPolicy = new SmartCardPinPolicy();
pinPolicy.MinLength = 6;

IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

SmartCardProvisioning provisioning = await
     SmartCardProvisioning.RequestVirtualSmartCardCreationAsync(
          "Card friendly name",
          adminkey,
          pinPolicy);

関連付けられた SmartCardProvisioning オブジェクトが RequestVirtualSmartCardCreationAsync から返されたら、仮想スマート カードのプロビジョニングが完了し、使う準備ができたことになります。Once RequestVirtualSmartCardCreationAsync has returned the associated SmartCardProvisioning object, the virtual smart card is provisioned and ready for use.

注意

UWP アプリを使用して仮想スマート カードを作成するには、アプリを実行しているユーザーは、administrators グループのメンバーにある必要があります。In order to create a virtual smart card using a UWP app, the user running the app must be a member of the administrators group. ユーザーが administrators グループのメンバーでない場合は、仮想スマート カードの作成は失敗します。If the user is not a member of the administrators group, virtual smart card creation will fail.

認証チャレンジの処理Handle authentication challenges

スマート カードや仮想スマート カードを使って認証するには、カードに格納されている管理者キーのデータと、認証サーバーまたは管理ツールによって管理されている管理者キーのデータとの間で、チャレンジを完了する動作をアプリに実装する必要があります。To authenticate with smart cards or virtual smart cards, your app must provide the behavior to complete challenges between the admin key data stored on the card, and the admin key data maintained by the authentication server or management tool.

次のコードは、サービスのスマート カード認証をサポートする方法、または物理カードや仮想カードの詳細を変更する方法の例を示します。The following code shows how to support smart card authentication for services or modification of physical or virtual card details. カードの管理者キーを使って生成されたデータ ("challenge") が、サーバーまたは管理者ツールから提供された管理者キーのデータ ("adminkey") と一致すれば、認証は成功します。If the data generated using the admin key on the card ("challenge") is the same as the admin key data provided by the server or management tool ("adminkey"), authentication is successful.

static class ChallengeResponseAlgorithm
{
    public static IBuffer CalculateResponse(IBuffer challenge, IBuffer adminkey)
    {
        if (challenge == null)
            throw new ArgumentNullException("challenge");
        if (adminkey == null)
            throw new ArgumentNullException("adminkey");

        SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesCbc);
        var symmetricKey = objAlg.CreateSymmetricKey(adminkey);
        var buffEncrypted = CryptographicEngine.Encrypt(symmetricKey, challenge, null);
        return buffEncrypted;
    }
}

このコードは、このトピックの残りの部分で説明する、認証操作を完了する方法や、スマート カードまたは仮想スマート カードの情報に変更を適用する方法の中で使われます。You will see this code referenced throughout the remainder of this topic was we review how to complete an authentication action, and how to apply changes to smart card and virtual smart card information.

スマート カードまたは仮想スマート カード認証の応答の確認Verify smart card or virtual smart card authentication response

これで認証チャレンジのロジックが定義されたので、リーダーと通信してスマート カードにアクセスするか、その代わりに仮想スマート カードにアクセスして、認証を行うことができます。Now that we have the logic for authentication challenges defined, we can communicate with the reader to access the smart card, or alternatively, access a virtual smart card for authentication.

  1. チャレンジを始めるには、スマート カードに関連付けられた SmartCardProvisioning オブジェクトから GetChallengeContextAsync を呼び出します。To begin the challenge, call GetChallengeContextAsync from the SmartCardProvisioning object associated with the smart card. これにより、SmartCardChallengeContext のインスタンスが生成されます。このインスタンスには、カードの Challenge 値が含まれています。This will generate an instance of SmartCardChallengeContext, which contains the card's Challenge value.

  2. 次に、カードのチャレンジ値とサービスまたは管理ツールから提供された管理者キーを、前の例で定義した ChallengeResponseAlgorithm に渡します。Next, pass the card's challenge value and the admin key provided by the service or management tool to the ChallengeResponseAlgorithm that we defined in the previous example.

  3. VerifyResponseAsync 戻りますtrue認証が成功した場合。VerifyResponseAsync will return true if authentication is successful.

bool verifyResult = false;
SmartCard card = await rootPage.GetSmartCard();
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

using (SmartCardChallengeContext context =
       await provisioning.GetChallengeContextAsync())
{
    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(
        context.Challenge,
        rootPage.AdminKey);

    verifyResult = await context.VerifyResponseAsync(response);
}

ユーザー PIN の変更またはリセットChange or reset a user PIN

スマート カードに関連付けられている PIN を変更するには、次の手順に従います。To change the PIN associated with a smart card:

  1. カードにアクセスし、関連付けられた SmartCardProvisioning オブジェクトを生成します。Access the card and generate the associated SmartCardProvisioning object.
  2. RequestPinChangeAsync を呼び出して、この操作を完了するための UI をユーザーに表示します。Call RequestPinChangeAsync to display a UI to the user to complete this operation.
  3. PIN が正しく変更された場合は、呼び出しから true が返されます。If the PIN was successfully changed the call will return true.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

PIN のリセットを要求するには、次の手順に従います。To request a PIN reset:

  1. RequestPinResetAsync を呼び出して操作を開始します。Call RequestPinResetAsync to initiate the operation. この呼び出しには、スマート カードと PIN のリセット要求を表す SmartCardPinResetHandler メソッドが含まれます。This call includes a SmartCardPinResetHandler method that represents the smart card and the pin reset request.

  2. SmartCardPinResetHandler 情報を提供する、 ChallengeResponseAlgorithmでラップされた、 SmartCardPinResetDeferral を呼び出すと、カードのチャレンジの値と要求の認証にサービスや管理のツールによって提供される管理キーを比較するために使用します。SmartCardPinResetHandler provides information that our ChallengeResponseAlgorithm, wrapped in a SmartCardPinResetDeferral call, uses to compare the card's challenge value and the admin key provided by the service or management tool to authenticate the request.

  3. チャレンジが成功すると、RequestPinResetAsync の呼び出しが完了し、PIN が正しくリセットされた場合は true が返されます。If the challenge is successful, the RequestPinResetAsync call is completed; returning true if the PIN was successfully reset.

SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinResetAsync(
    (pinResetSender, request) =>
    {
        SmartCardPinResetDeferral deferral =
            request.GetDeferral();

        try
        {
            IBuffer response =
                ChallengeResponseAlgorithm.CalculateResponse(
                    request.Challenge,
                    rootPage.AdminKey);
            request.SetResponse(response);
        }
        finally
        {
            deferral.Complete();
        }
    });
}

スマート カードまたは仮想スマート カードの取り外しRemove a smart card or virtual smart card

物理スマート カードが取り外されると、カードの削除時に CardRemoved イベントが発生します。When a physical smart card is removed a CardRemoved event will fire when the card is deleted.

カード リーダーでこのイベントが発生したときのイベント ハンドラーとして、カードまたはリーダーが取り外されたときのアプリの動作を定義するメソッドを関連付けます。Associate the firing of this event with the card reader with the method that defines your app's behavior on card or reader removal as an event handler. この動作は、カードが取り外されたことをユーザーに通知するといった単純なものでかまいません。This behavior can be something as simply as providing notification to the user that the card was removed.

reader = card.Reader;
reader.CardRemoved += HandleCardRemoved;

仮想スマート カードの削除はプログラムによって行います。まずカードを取得し、次に SmartCardProvisioning によって返されたオブジェクトから RequestVirtualSmartCardDeletionAsync を呼び出します。The removal of a virtual smart card is handled programmatically by first retrieving the card and then calling RequestVirtualSmartCardDeletionAsync from the SmartCardProvisioning returned object.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);