brunch

You can make anything
by writing

C.S.Lewis

by Chansuk Yang Mar 18. 2019

안드로이드 Q 기기 고유 식별자(IMEI 등) 제한

개발자를 위한 안드로이드 Q #3


시작하기 전에...

본 포스트는 디바이스 ID 관련된 내용을 다루며, 3월 14일 공개된 안드로이드 Q 베타 버전 기준으로 작성되었습니다. 이후, 정식 버전에서는 기능 및 API가 변경될 수 있으며, 기능에 관한 소감이나 의견은 개인적인 의견으로 회사의 공식 의견과는 다를 수 있습니다. 


TL;DR;

안드로이드 Q 버전부터는 더 이상 '사용자가 재설정할 수 없는' 디바이스 식별자를 제공하지 않습니다. 타깃 SDK 버전과 관계없이 DeviceID, IMEI, MEID, Build.Serial 등의 값을 사용할 수 없습니다. 만일 이러한 디바이스 식별자를 사용하고 있다면, 다른 방법으로 전환해야 합니다. 디바이스 식별자를 사용하고 있는 방식에 따라 마이그레이션 작업에 많은 시간이 소요될 수 있기 때문에 주의가 필요합니다.


사용자가 재설정할 수 없는(Non-resettable) 식별자? 

안드로이드 플랫폼에는 고유 식별자로 사용할 수 있는 값이 여럿 있습니다. 고유 식별자의 종류와 특징에 대해서는 공식 개발자 문서에 잘 정리되어 있습니다. 혹시 아직 살펴보지 못하셨다면, 우선 해당 문서의 내용을 잘 확인해 보시면 좋을 것 같네요. 기본적으로 고유 식별자는 식별자의 '범위'와 '수명' 두 가지 기준으로 나눌 수 있습니다. 


먼저, 고유 식별자의 범위는 대략적으로 다음과 같이 분류됩니다. 

단일 앱 - 한 앱에서 확인한 식별자는 해당 앱에서만 동일하게 유지됩니다. 앱 A에서 확인한 식별자는 앱 B에서 확인한 식별자와 다릅니다. 

앱 그룹 - 한 앱에서 확인한 식별자는 미리 정의된 몇몇 앱 사이에서 동일하게 유지됩니다. 예를 들어 앱 서명키 기준으로 앱 그룹을 지정할 수 있습니다. 앱 A에서 확인한 식별자는 동일 키로 서명된 앱 B에서 확인한 식별자와 동일합니다. 서명 키가 다른 앱 C에서는 값이 달라집니다. 

디바이스 - 한 앱에서 확인한 식별자는 동일 디바이스에 있는 모든 앱에서 동일하게 유지됩니다. 동일 디바이스에 설치된 앱 A, B, C 모두 동일한 식별자 값을 갖습니다.


참고로, 만일 하나 이상의 사용자 프로파일(게스트 계정 등)을 사용하는 경우, 프로파일 별로 설치된 앱이 독립적으로 관리됩니다. 이런 경우에 디바이스 범위의 식별자는 유지되겠지만, 단일 앱 혹은 앱 그룹 범위의 식별자 값은 변경될 수 있습니다. 다시 말해, 같은 앱이라도 사용자 프로파일이 달라지면 다른 식별자를 갖게 됩니다. 


고유 식별자의 수명은 대략 다음과 같이 분류할 수 있습니다.

세션 - 사용자가 앱을 실행 후 종료할 때까지 고유 식별자 값이 유지됩니다. 사용자가 앱을 종료 후 다시 시작하면, 식별자 값이 달라집니다.

앱 설치 - 고유 식별자가 사용자가 앱을 삭제 후 재설치하거나, 앱 데이터를 삭제하기 전 까기 유지됩니다. 

디바이스 초기화 (DFR - Device Factory Reset) - 디바이스를 초기화하기 전까지 고유 식별자가 유지됩니다. 사용자가 앱을 삭제 후 재설치하는 경우에도 식별자 값이 동일합니다. 

디바이스 초기화 후에도 유지 - 디바이스 공장 초기화를 하는 경우에도 고유 식별자가 유지됩니다. 기본적으로 사용자는 식별자 값을 변경할 수 없습니다. 이러한 수명을 갖는 식별자가 이른바 사용자가 재설정할 수 없는(Non-resettable) 식별자입니다.

당연히 고유 식별자 범위가 넓고 수명이 길 수록 오랜 시간에 걸쳐 특정 사용자 행동을 추적할 수 있는 위험성이 생깁니다. 디바이스 초기화 후에도 계속 유지되는 값들은 아예 사용자가 재설정할 수 있는 방법이 없고, 디바이스 주인이 변경되는 경우에도 값이 유지되기 때문에 잠재적인 위험성 및 예기치 못한 문제가 발생할 가능성이 더욱 높습니다. 


원칙적으로 안드로이드 플랫폼에서는 수명이 긴 식별자 사용을 권장하지 않았습니다 (안드로이드 고유 식별자 사용에 관한 첫 번째 규칙입니다 - #1. Avoid using hardware identifiers). 그동안 플랫폼 차원에서도 변화가 있었습니다. 안드로이드 6.0부터는 MAC 주소 접근이 금지되었습니다 (wlan0 파일을 직접 읽어오는 구멍이 있었지만, 이것도 7.0에서 막혔습니다 :p). 안드로이드 8.0부터는 ANDROID_ID 값이 범위가 기존 디바이스 범위에서 서명 키 기반 앱 그룹으로 범위가 조정되었습니다. 더 나아가, 이번 Q 버전에서는 디바이스 초기화 후에도 유지되는 식별자에는 아예 접근할 수 없도록, 플랫폼 정책이 더욱 강화됩니다.


안드로이드 Q에서의 디바이스 고유 식별자

그럼 기존에 널리 활용되었던 '사용자가 재설정할 수 없는 고유 식별자 값'을 가져오면 어떻게 될까요? 간단히 확인해보았습니다.


TelephonyManager#getDeviceId() - 'null' 반환

TelephonyManager#getImei() - 'null' 반환

TelephonyManager#getMeid() - 'null' 반환

Build.getSerial() - unknown 반환

Build.SERIAL - unknown 반환

WifiInfo.getMacAddress() - 02:00:00:00:00:00 반환


타깃 SDK 버전이 28 (안드로이드 Pie)인 아주 간단한 테스트 앱으로 확인해본 결과입니다. 문서에 정리된 대로 재설정할 수 없는 고유 식별자 값이 'null' 혹은 'unknown'으로 나오며, MAC 주소는 이전 버전과 동일하게 '02:00:00:00:00:00' 고정된 값이 반환됩니다. 혹시 네트워크 트래픽 정보를 이용해 고유 식별자 혹은 사용자 행동을 분석하는데 활용하고 계신다면 주의할 점이 한 가지 더 있습니다. Q 버전부터는 '/proc/net' 파일 시스템 접근이 금지됩니다. 만일 디바이스 네트워크 상태 정보를 꼭 확인해야 한다면, NetworkStatsManager 혹은 ConnectivityManager 클래스를 사용하라고 하네요. 


여기까지 제가 아는 주요 고유 식별자는 모두 테스트해 보았습니다. 혹시 이 외에도 다른 형태로 디바이스 고유 식별자를 확인해 사용하고 계신다면, 댓글로 알려주시면 감사하겠습니다 : )


권장 사항

공식 개발자 문서에 잘 정리된 내용이긴 하지만, 한글 버전의 내용이 영문 내용과 조금 다른 점도 있고 ㅠㅠ 한 번 정리해두면 개인적으로도 도움이 될 것 같아, 활용 가능한 대안을 나름 고민해 보았습니다. 필요한 시나리오에 따라 식별자의 범위와 수명을 잘 따져본 후, 가장 맞는 식별자를 선택하면 좋을 것 같습니다.

일단 사용이 제한되는 식별자를 대신해 사용할 수 있는 권장 식별자는 다음과 같습니다. 

안드로이드 고유 식별자 종류와 특징

광고 ID (Advertisement Id) - 디바이스 범위 식별자입니다. 사용자가 디바이스 초기화 혹은 명시적으로 광고 ID 초기화를 선택하기 전까지 계속 유지됩니다. 사용 시에는 구글 플레이의 Android 광고 ID 사용 정책을 잘 준수해야 합니다.

InstaceID (FirebaseInstanceID) 혹은 GUID - 앱 범위의 식별자입니다. 구현 방식에 따라 특정 앱 그룹 간에 식별자를 공유할 수도 있습니다 (서비스 혹은 공유 파일 등의 방식으로 한 앱에서 생성한 식별자를 다른 앱에 전달하는 방식으로). 사용자가 앱을 삭제하거나 앱 데이터를 삭제하기 전까지 유지됩니다. 대부분의 경우 권장되는 식별자입니다. 기존 InstaceID 클래스는 더 이상 지원되지 않으며, FirebaseInstanceID 클래스 (Firebase 연동이 필요) 혹은 직접 GUID를 생성하는 방식으로 적용할 수 있습니다. 

SSAID (Settings.Secure.ANDROID_ID) - 안드로이드 8.0 이상부터는 앱 그룹 범위, 그 전에는 디바이스 범위 식별자입니다. 8.0 이상부터는 서명 키가 동일한 앱은 동일한 식별자 값을 갖습니다. 식별자는 디바이스 초기화 전까지 유지됩니다. 다시 말해, 앱 삭제 후 재설치 시에도 식별자가 동일합니다. 원칙적으로 안드로이드 8.0 미만 버전에서는 사용을 권장하지 않습니다. 8,0 이상 버전이나 혹은 유료 콘텐츠 보호 등을 위해 수명이 긴 고유 식별자가 필요한 경우 (광고 ID와 InstanceID는 재설정이 쉬워 악성 사용자가 쉽게 변경할 수 있음) 적용할 수 있습니다. 

4월 18일 추가 - 대안으로 사용가능한 또 하나의 식별자, Widevine ID 사용에 관한 내용은 4월 17일 포스팅한 DRM 기기 식별자 활용하기 브런치 포스트를 참고하시기 바랍니다. 

마지막으로, 사용 용처가 명확한 경우를 제외하고 (예를 들어, 사용자 맞춤 광고를 위한 트래킹 목적으로 광고 ID 사용), 고유 식별자가 필요한 몇 가지 재미있는 케이스를 살펴보고 개인적인 의견을 정리해보았습니다.


1. 콘텐츠 접근 디바이스 수 제한하기 위해 고유 식별자가 필요한 경우

제한하는 대상은 디바이스이지만, 사용자는 결국 앱을 통해 콘텐츠에 접근합니다. 따라서 앱 범위의 식별자를 사용할 수 있습니다. 다만 Instance ID와 같이 사용자가 너무 쉽게 재설정할 수 있는 식별자를 사용하는 경우, 사용자가 의도치 않게 식별자를 변경해 불이익을 받을 수도 있습니다 (예를 들어 3대의 디바이스에서만 접근 가능한데, 사용자가 앱 용량을 줄이기 위해 앱 데이터를 삭제하는 경우, 새로운 디바이스로 인식되어 콘텐츠 접근이 막힘). 이런 예외 케이스는 앱 내에서 UX적으로 해결할 수 있고, 혹은 재설정이 힘든 SSAID 값을 고유 식별자로 사용할 수도 있습니다.  


2. 부정 사용이 의심되는 디바이스 / 사용자를 제한하기 위해

만일 특정 사용자가 악의적인 행동(DDOS 공격이나 악의적 매크로 등)을 하는 것을 감지하고 이를 차단하기 위해 고유 식별자를 사용하는 경우, 디바이스 범위의 식별자 사용을 고려할 수 있습니다. 하지만, 이는 효과적이지 않습니다. 악성 사용자가 사용하는 디바이스는 에뮬레이터 혹은 루팅 된 OS가 설치된 비정상적인 안드로이드 디바이스일 가능성이 높고, 사용자가 쉽게 디바이스 식별자를 변경할 수 있습니다. 따라서, 단말 단에서 쉽게 위조가 가능한 디바이스 식별자를 사용하는 대신, 디바이스의 무결성을 검증할 수 있는 다른 수단(예를 들어 구글에서 제공하는 SafetyNet Attestation API)을 활용해 먼저 디바이스 무결성을 인증한 후, 다른 추가적인 신호를 조합해 활용할 것을 권장합니다. 


3. 동일 회사에서 제공하는 서로 다른 앱 간의  프로모션이나 사용자 트래킹을 위해

만일 하나 이상의 앱을 사용자에게 제공하고 있는 경우, 한 사용자가 자사의 앱 중 어떤 앱을 사용하고 있는지에 따라 전체 서비스의 동작 방식이 달라질 수 있습니다 (예를 들어, 이미 유료 버전 앱과 무료 버전 앱을 모두 설치한 사용자에게는 유료 버전 앱을 홍보하는 알림을 보내지 않는 등). 자사 앱 간의 마케팅이나 사용자 트래킹을 위해서는 앱 그룹 범위의 식별자가 필요합니다. 만일, 서비스 중인 앱들이 동일 서명 키로 서명된 경우 (일반적으로 권장되는 방식입니다) SSAID를 활용할 수 있습니다. 서명 키가 다른 경우, 앱 자체적으로 GUID를 생성한 후, 해당 ID를 다른 앱과 공유하는 방식을 고민해봐야 합니다.


지금까지 디바이스 식별자의 종류와 주요 변경 사항을 살펴보았습니다. 디바이스 식별자는 사용하고 있는 방식에 따라 매우 복잡하고 긴 (그리고 가슴 철렁한 ㅠㅠ) 마이그레이션 작업이 필요할 수도 있는 만큼 (예를 들어, 서버 쪽에서 특정 식별자를 사용자 구분 용도로 사용하고 있어서, 서버 마이그레이션이 필요한 등), 주의 깊게 살펴보시면 좋을 것 같습니다. 현재 앱에서 어떤 식별자를 어떤 용도로 사용하고 있는지 확인한 후, 이 포스트에서 소개한 광고 ID, InstanceID, SSAID 등의 대안으로 해결하기 어려운 사용처가 있다면, 같이 고민해볼 수 있도록 댓글 남겨주셔도 좋을 것 같습니다 : ) 


개발자를 위한 안드로이드 Q 정리

개발자 주의가 예상되는 안드로이드 Q의 변경 사항을 정리해 '개발자를 위한 안드로이드 Q 정리'라는 브런치 매거진으로 발행하고 있습니다. 


우선적으로 베타 1 버전에는 개발자들의 주의가 필요한 (그래서 무서운) 동작 변경 사항에 관해 주로 다루었지만, 이후 베타 2 버전이 공개되면, 개발자 입장에서 재밌고 새롭게 적용해볼 만한 신기능에 관해서도 다루어 볼 예정입니다 (그런 게 있겠죠?). 그런 만큼, 안드로이드 Q 버전이 정식 출시될 때까지, 
'개발자를 위한 안드로이드 Q 정리 매거진'에 많은 관심 부탁드립니다 : ) 

매거진의 이전글 안드로이드 Q Scoped Storage 이해하기
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari