tanamonの稀に良く書く日記

KEEP CALM AND DRINK BEER

[memo]UDID/UUID/UIIDなどとiOS6の新IDの違い

UなんとかIDみたいなのがいっぱいあって区別がつかないので少し整理してみた。


なんとかIDの種類。

UDID(Unique Device IDentifier)

(たぶん)Apple用語。
iOS端末の製造時に割り当てられる固有の識別コードで、値の変更はできない。
端末IDや端末固定IDと呼ばれるものと同じ。
iOS5からアプリからの取得が非推奨になった。

UUID(Universally Unique IDentifier)

RFC 4122で定義されている。
生成の度に値が変わり、理論上重複することがない。
実装的にはGUID(Globally Unique IDentifier)が有名。
iOS6からNSUUIDクラスを使って簡単に生成できるようになった。

UIID(Unique Installation IDentifier)

インストールごとに変わるという性質を持ったUUID。
そのため、アプリを複数回インストールするとその都度別の値になる。
アプリの初回起動時にUUIDを生成してストレージに保存しておくという実装が一般的かと思われる。

OpenUDID

GitHub - ylechelle/OpenUDID: [OpenUDID IS NOW DEPRECATED] Open source initiative for a universal and persistent UDID solution for iOS
iOS端末のUDIDへのアクセスが禁止されたことによる代替案らしい。
性質はUDIDとほぼ同じで、オプトアウトできる(= 拒否権を行使できる、要は利用者都合で値を再生成できる)。
実装はiOS/Android/Windows Phoneがあるが、オプトアウトはiOS版のみ可能。

SecureUDID

GitHub - crashlytics/secureudid: DEPRECATED - SecureUDID is an open-source sandboxed UDID solution aimed at solving the main privacy issues that caused Apple to deprecate UDIDs.
OpenUDIDがセキュアじゃない(特に複数ベンダー間で同一値を用いるところ)ため、代替案として作られたもの。
OpenUDIDと比べると、ベンダーごとに違う値が生成されるという点が異なる。
実装は今のところiOSのみ。

UIDevice.identifierForVendor

UDIDの代替としてiOS6から使える公式実装。
端末固定でベンダーごとに値が変わるので、性質的にはSecureUDIDに近い。
ターゲットをiOS6以降にできるなら、SecureUDIDの代わりにこちらを使った方がいい。

ASIdentifierManager.advertisingIdentifier

UDIDの代替としてiOS6から使える公式実装(その2)。
UIDevice.identifierForVendorとは違い、全ベンダー共通のためUDIDに近い。
ただし、UDIDと違い、オプトアウトできる。
(オプトアウトは設定アプリの情報>アドバタイズにある「Ad Trackingを制限」で設定)

特徴

で、それぞれ、どの程度一意性があるかをまとめてみるとこんな感じになった。

一意性の範囲 UDID UUID UIID OpenUDID SecureUDID IDFV ASID 電話番号 MACアドレス
永久一意性*1 ×*2
IDを利用する度 ×
再インストール × ×
同V複数アプリ間 × ×
複数ベンダー間 × × × ×
機種変更 × × × × × × × ×
複数機種利用 × × × × × × × × ×
利用者の変更*3 × × × × × × ×

(比較のために他の一意情報である電話番号とMACアドレスを入れてみました)
○ = 値が変わらない、× = 値が変わる


こうして一覧にすると、

  • UDIDとMACアドレスは、他人の手に渡った後も同一IDとなってしまう(かなりキケン)
  • 電話番号は、将来的に他人と紐付けてしまう可能性があるため、そもそも一意かという点で微妙(キケン)
  • OpenUDIDは、IDが漏洩すると利用者の意図しない範囲までの情報が紐づけ可能となる(キケン)

ということがわかる。これらは一意性を保つための情報としては不適切じゃないかと思う。

ここらへんの危険物を避けた上で、残りものを用途別に見ていくと、

UUID

端末内の一意な名称(テンポラリなファイル名など)を区別するために使う。
ただしサーバが介在する場合は、サーバ側でUUID相当のものを発行した方がいいと思う。
(ちなみに、ありがちな{年月日時分秒}.pngみたいなのは、端末時刻をユーザが変更できる環境では一意になるとはいえないため、UUIDを用いること)

UIID

ユーザ認証を持たずにユーザを特定して、サーバとの通信を行うような場合に使う。
アプリ間で共通のIDを持つ必要性がない場合はこれを使うのがよい。
(基本的に意図せぬ範囲にIDが公開されないように、共通性は抑えておいたほうがよいため)

SecureUDID

複数のアプリを提供しているベンダーが、ユーザを特定するためにUDIDの代わりとして使う。
iOS5以前の環境でも利用したい場合のみ、iOS6以降だけならUIDevice.identifierForVendorを使う。

UIDevice.identifierForVendor

複数のアプリを提供しているベンダーが、ユーザを特定するためにUDIDの代わりとして使う。
(使い勝手がいいということで)今後はこれが主流になるかと*4

ASIdentifierManager.advertisingIdentifier

iAdのような広告提供用ライブラリ内で使うなど、かなり特殊用途だと思う。
オプトアウトできるとはいえ、普通の開発者は手を出さないほうがいいかと。


なお、これらのIDでカバーされていない領域の機種変更・複数機種利用は、ここら辺はOAuthなどのアクセストークンと組み合わせて繋げておくべきところだと思う。

*1:同じIDが今後も含め二度と振られないという(理論上ほぼ完全な)一意性を持つかどうか

*2:たしか携帯電話番号は解約してしばらく経つと同じ番号が振られたはず

*3:中古屋さんに売ったり、友人に譲渡したりというような想定

*4:個人的にはこれ単体で一意とするのではなくUIIDと併用するようにして、必要最低限のものだけ持つように実装してほしい