BETA

接触確認アプリ「COCOA」が端末と陽性者情報を紐づけできる可能性

投稿日:2020-07-15
最終更新:2020-07-16

厚生労働省が公開した接触確認アプリ「COCOA」のベースであるCovid19Radarは、処理番号登録時にDeviceCheckのTokenを送信しています。DeviceCheckでは端末を直接識別することはできませんが、端末に対して永続的なフラグを設定することができるため、端末と「陽性者である」という情報を紐づけできる可能性が存在します。

DeviceCheckについて

DeviceCheckはiOSに組み込まれた、端末の整合性を検証するためのフレームワークです。このフレームワークでは端末を検証したり、端末ごとに2bitの値を設定することができます。

https://developer.apple.com/documentation/devicecheck

クライアント側とサーバー側の処理で構成されます。

  • クライアント側ではTokenを取得してサーバーに送信します
  • サーバー側ではTokenを使用してAppleのAPIと連携して結果を受け取ります

サーバー側で呼び出せるAPIは以下の通りです。

  1. 端末を検証する(Validation Request)
  2. 2bitの値を取得する (Query Request)
  3. 2bitの値を更新する(Update Request)

アプリ単位ではなく開発者単位で管理されるため、ある端末に対して設定した2bitの値は同じ開発者がリリースする全てのアプリから参照することができます。設定した2bitの値はAppleのサーバーに保存され、アプリの削除や端末の初期化を実施しても自動的にはリセットされません。

陽性診断時の処理番号登録処理について

Covid19Radarは陽性診断時の処理番号登録処理において、他の情報と合わせてDeviceVerificationPayloadという値を送信しています。

// ExposureNotificationHandler.cs  

// Create the submission  
var submission = new DiagnosisSubmissionParameter()  
{  
    UserUuid = userData.UserUuid,  
    Keys = keys.ToArray(),  
    Regions = AppSettings.Instance.SupportedRegions,  
    Platform = DeviceInfo.Platform.ToString().ToLowerInvariant(),  
    DeviceVerificationPayload = null,  
    AppPackageName = AppInfo.PackageName,  
    VerificationPayload = pendingDiagnosis.DiagnosisUid,  
    Padding = padding  
};  

// See if we can add the device verification  
if (DependencyService.Get<IDeviceVerifier>() is IDeviceVerifier verifier)  
{  
    submission.DeviceVerificationPayload = await verifier?.VerifyAsync(submission);  
}  
return submission;  

iOSの場合、DeviceVerificationPayloadにはDeviceCheckのTokenが使われます。

// DeviceCheckService.cs  

public class DeviceCheckService : IDeviceVerifier  
{  
    public async Task<string> VerifyAsync(DiagnosisSubmissionParameter submission)  
    {  
        var token = await DeviceCheck.DCDevice.CurrentDevice.GenerateTokenAsync();  
        return Convert.ToBase64String(token.ToArray());  
    }  

}  

サーバー側では受け取ったTokenを使用して端末の検証を実施しています。

// DeviceValidationAppleService.cs  

public class DeviceValidationAppleService  
{  
    ...  

    const string UrlApple = "https://api.devicecheck.apple.com/v1/validate_device_token";  

    ...  

    /// <summary>  
    /// Validation iOS  
    /// </summary>  
    /// <param name="param">subumission parameter</param>  
    /// <returns>True when successful.</returns>  
    /// <remarks>  
    /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data  
    /// </remarks>  
    public async Task<bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime, AuthorizedAppInformation app)  
    {  
        var payload = new ApplePayload()  
        {  
            DeviceToken = param.DeviceVerificationPayload,  
            Timestamp = requestTime.ToUnixTimeMilliseconds()  
        };  

        ...  

        var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey);  

        var payloadJson = JsonConvert.SerializeObject(payload);  
        Logger.LogInformation($"{nameof(Validation)} payload:{payloadJson} ");  
        var request = new HttpRequestMessage(HttpMethod.Post, UrlApple);  
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);  
        request.Content = new StringContent(payloadJson, Encoding.UTF8, "application/json");  
        try  
        {  
            var response = await ClientApple.SendAsync(request);  
            ...  
        }  
        catch (Exception ex)  
        {  
            Logger.LogError(ex, $"{nameof(Validation)}");  
            throw;  
        }  
    }  

陽性者情報との紐づけ可能性について

DeviceCheckのTokenはクライアント側で作成する際に、その利用用途について限定しません。クライアントからサーバーへ送信されたTokenは端末の検証だけではなく、2bitの取得・設定にも使用することが可能であり、それはサーバー側の実装次第です。

例えば、Tokenを使用して処理番号を送付してきた端末のbit0をtrueに設定した場合、その時点で端末と「陽性者である」という情報が紐づくことになります。接触確認アプリだけでなく、厚生労働省がリリースする全てのアプリにおいてこのbit0を参照することで端末が陽性者のものであるかどうかを判断できる状態になります。端末を初期化してもこの情報はリセットされないため、永続的に紐づいた状態となります。

上に貼ったようにCovid19Radarのサーバー実装では検証用途にのみ使用しているので問題はありません。しかし、接触確認アプリがCovid19Radarと同じ実装になっている保証はありません。ドキュメントを参照すると接触確認アプリとCovid19Radarは同一ではないことが明記されています。(*1)

対応方法

クライアント側でDeviceCheckのTokenを送信しないように改修すればこの懸念はなくなります。サーバー側で端末の検証が行えなくなりますが、このアプリにおいては必須の処理ではないはずです。

そもそもCovid19RadarがDeviceCheckを使用しているのは、GoogleのExposure Notificationサーバー実装を参照していたためと思われます。(追記: これは誤認でした。 ページ下部 *2 を参照してください。)

しかし、Google側では6月1日に同実装を削除しています。
Remove DeviceCheck and SafetyNet (#507)

Covid19Radarおよび接触確認アプリにおいても、この処理を削除して利用者に余計な懸念を与えないように配慮したほうが良いのではないでしょうか。

*1 Covid19RadarのREADMEによると、"厚労省の公式アプリのコードそのものではなく、公式アプリの元になっているオープンソースコードです。"

*2 (追記) 当初はGoogle のExposure Notificationサーバー実装を参照してCovid19Radarチームが独自に実装したものと見ていたのですが、再度コードを確認したところXamrinのサンプル実装を流用されているようでした。本文中の結論には影響ありません。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

⭐オススメ技術ブログ⭐

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう