안드로이드는 휴대폰을 구분할 수 있는 변경 불가능한 식별자(이하 편의상 UID, Unique identifier)를 제공해 왔다. 공식 문서에 언급된 API들은 아래와 같다.
Build
TelephonyManager
Build나 TelephonyManager 클래스를 통해 제공되는 이 기능이 안드로이드 10(API29 혹은 Q OS)부터 개인정보 보호 강화 정책에 따라 추가 제약을 받는다고 한다. targetSdkVersion 기준 28까지는 READ_PHONE_STATE 권한을 가진 앱은 UID를 읽을 수 있으나, 29부터 READ_PRIVILEGED_PHONE_STATE 권한이 있어야 한다. 그러므로, TelephonyManager.getDeviceId() API를 각각 O OS와 Q OS에서 호출한다면 아래와 같이 동작할 것이다.
O OS + READ_PHONE_STATE 권한이 없을 때
Caused by: java.lang.SecurityException: getDeviceId: uid 10237 does not have android.permission.READ_PHONE_STATE.
O OS + READ_PHONE_STATE 권한이 있을 때
2019-12-31 14:59:56.528 32231-32231/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= 230064929080355
Q OS + READ_PHONE_STATE 권한이 없을 때
Caused by: java.lang.SecurityException: getDeviceId: The user 10265 does not meet the requirements to access device identifiers.
Q OS + READ_PHONE_STATE 권한이 있을 때
2019-12-31 14:54:39.741 5812-5812/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= null
Q OS + READ_PRIVILEGED_PHONE_STATE 권한이 있을 때
2019-12-31 14:59:56.528 32231-32231/me.sunphiz.android.myapplication2 D/sunphiz: deviceId= 230064929080355
그럼 READ_PRIVILEGED_PHONE_STATE 권한은 어떻게 얻을 수 있을까? 결론만 이야기하면, 다운로드 앱(구글 플레이 스토어 등에서 다운받아 설치한 앱)은 저 권한을 얻을 방법이 없다. 저 퍼미션이 선언된 시스템의 AndroidManifest.xml을 보면, protectionLevel이 signatureOrSystem이기 때문이다. 이 조건은 단말 제조사만 충족할 수 있으므로, 다운로드 앱은 targetSdkVersion 29부터 UID에 접근할 수 없다는 결론이 된다.
그럼 어떻게하란 말인가? UID를 이용하던 기능이 있다면, 아래 방법 중 하나를 적용해보자.
- targetSdkVersion을 28이하로 유지
- ‘광고 및 사용자 분석을 위한 고유 식별자‘로 대체 고려
- ‘Android 식별자 사용 권장사항‘을 보고 기능 변경
그 밖에
UID는 변경이 불가능한 값이라 편리하다. 동시에, 내 서비스를 통해 값이 유출된다면 의도치 않은 사용자 피해가 생긴다. 조금 번거롭더라도 더 안전한 방향으로 개선하자.
참조
- https://en.wikipedia.org/wiki/Unique_identifier
- https://developer.android.com/about/versions/10/privacy/changes#non-resettable-device-ids
- https://stackoverflow.com/questions/55173823/i-am-getting-imei-null-in-android-q
- https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml#2067
- https://sunphiz.me/wp/archives/3332
- https://developer.android.com/about/versions/10/privacy/changes#data-ids
- https://developer.android.com/training/permissions/usage-notes#d_create_a_unique_identifier_for_advertising_or_user_analytics