본문 바로가기

Android[Kotlin]

[Android][kotlin] 안드로이드 기기 고유 값

MVP 1차 출시 때는 로그인, 회원가입을 만들지 않기로 했다. 

서버에서 로그인과 회원가입이 없으니까, 사용자를 구분할 수 있는 기기 고유값이 필요하다고 한다.

기기 고유값을 표현할 수 있는 것들은 무엇이 있고 그 특징이 뭔지?

고유 식별자가 필요한 상황들은 어떤것들이 있을지?

왜 사용자를 구분해야 하는지?

우리의 목적에 맞는 방법은 무엇일지?를 알아보고 선택해 봐야겠다.

 

안드로이드 공식문서

https://developer.android.com/training/articles/user-data-ids?hl=ko

 

고유 식별자 권장사항  |  Android 개발자  |  Android Developers

고유 식별자 권장사항 이 문서에서는 사용 사례에 따라 앱에 적합한 식별자를 선택하는 방법을 설명합니다. Android 권한과 관련된 일반적인 내용은 권한 개요를 참조하세요. Android 권한을 사용하

developer.android.com

Android 식별자 사용 권장사항
Android 식별자를 사용할 때는 다음 권장사항을 따르세요.
하드웨어 식별자 사용을 피합니다. 대부분의 사용 사례에서 필수 기능을 제한하지 않고도 SSAID(Android ID)와 같은 하드웨어 식별자를 사용하지 않을 수 있습니다.
Android 10(API 수준 29)에는 IMEI와 일련번호가 포함된 재설정이 불가능한 식별자에 관한 제한사항이 추가됩니다.
이러한 식별자에 액세스하려면 앱이 기기 또는 프로필 소유자 앱이거나 앱에 이동통신사 특별 권한 또는 READ_PRIVILEGED_PHONE_STATE 권한이 있어야 합니다.
사용자 프로파일링이나 광고 사용 사례에는 광고 ID만 사용합니다. 
광고 ID를 사용할 때는 항상 광고 추적과 관련하여 사용자의 선택을 존중합니다.
또한, 식별자를 PII(개인 식별 정보)에 연결해서는 안 되며 광고 ID 재설정 연결을 피해야 합니다.
결제 사기 예방 및 전화 통신을 제외한 기타 모든 사용 사례에는 가능하면 항상 인스턴스 ID 또는 비공개로 저장된 GUID를 사용합니다. 
광고 이외의 사용 사례 대부분은 인스턴스 ID GUID만으로 충분합니다.
사용 사례에 적합한 API를 사용하여 개인정보 유출 위험을 최소화합니다. 
중요한 콘텐츠 보호에는 DRM API를, 악용 방지에는 SafetyNet API를 사용하세요.
SafetyNet API는 개인정보 보호의 위험을 초래하지 않고 기기의 진위 여부를 확인할 수 있는 가장 쉬운 방법입니다.
이 가이드의 나머지 섹션에서는 Android 앱 개발 관점에서 이러한 규칙을 자세히 설명합니다.
...
인스턴스 ID와 GUID 사용
기기에서 실행 중인 앱 인스턴스를 식별하는 가장 단순한 방법은 인스턴스 ID를 사용하는 것입니다.
이것은 광고 이외의 대다수 사용 사례에 권장되는 해결 방법입니다.
인스턴스 ID가 프로비저닝되었던 앱 인스턴스만 이 식별자에 액세스할 수 있으며,
인스턴스 ID는 앱이 설치된 동안만 지속되므로 비교적 쉽게 재설정할 수 있습니다.
따라서, 인스턴스 ID는 재설정할 수 없는 기기 범위의 하드웨어 ID보다 더 나은 개인정보 보호 속성을 제공합니다. 자세한 내용은 FirebaseInstanceId API 참조를 확인하세요.
인스턴스 ID가 실용적이지 않은 경우 맞춤 GUID(Globally-Unique ID)를 사용해 앱 인스턴스를 고유하게 식별할 수도 있습니다. 이를 위한 가장 간단한 방법은 다음 코드로 나만의 GUID를 생성하는 것입니다.
   var uniqueID = UUID.randomUUID().toString()​

이 식별자는 전역적으로 고유하므로 특정 앱 인스턴스를 식별하는 데 사용될 수 있습니다.
여러 앱 간 식별자 연결과 관련된 문제를 방지하려면 GUID를 외부(공유) 저장소가 아닌 내부 저장소에 저장하세요. 자세한 내용은 
데이터 및 파일 저장소 개요 페이지를 참조하세요.

출처 : https://brunch.co.kr/@huewu/9

종류(사용가능)

InstaceID (FirebaseInstanceID) 혹은 GUID 

앱 범위의 식별자입니다.

구현 방식에 따라 특정 앱 그룹 간에 식별자를 공유할 수도 있습니다 (서비스 혹은 공유 파일 등의 방식으로 한 앱에서 생성한 식별자를 다른 앱에 전달하는 방식으로).

사용자가 앱을 삭제하거나 앱 데이터를 삭제하기 전까지 유지됩니다.

대부분의 경우 권장되는 식별자입니다.

기존 InstaceID 클래스는 더 이상 지원되지 않으며, FirebaseInstanceID 클래스 (Firebase 연동이 필요) 혹은 직접 GUID를 생성하는 방식으로 적용할 수 있습니다. 

 

광고 ID (Advertisement Id) 

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

 

SSAID (Settings.Secure.ANDROID_ID)

안드로이드 8.0 이상부터는 앱 그룹 범위, 그 전에는 디바이스 범위 식별자입니다.

8.0 이상부터는 서명 키가 동일한 앱은 동일한 식별자 값을 갖습니다.

식별자는 디바이스 초기화 전까지 유지됩니다. 

다시 말해, 앱 삭제 후 재설치 시에도 식별자가 동일합니다. 

원칙적으로 안드로이드 8.0 미만 버전에서는 사용을 권장하지 않습니다. 

8.0 이상 버전이나 혹은 유료 콘텐츠 보호 등을 위해 수명이 긴 고유 식별자가 필요한 경우 (광고 ID와 InstanceID는 재설정이 쉬워 악성 사용자가 쉽게 변경할 수 있음) 적용할 수 있습니다. 

추가참고 사용자가 재설정 가능하다. (하지만 조금 힘든건가 보다.) 따라서 덜 민감한 개인정보로 여겨질 수도 있다.

하지만 특정 사용자 시나리오에서는(예를들어 악성 사용자를 영구적으로 접근 금지시키거나, 기기마다 한번만 제공하는 프로모션 등) 기기 초기화 후에도 유지되는 식별자가 필요할 수 있고, 이 경우에는  MediaDrm API를 통한 WidevineID 도 사용을 고려해 볼 수 있다고 한다

 private fun getDeviceUuid(): String? {
        return Settings.Secure.getString(
            applicationContext.contentResolver,
            Settings.Secure.ANDROID_ID
        )
    }

종류(사용불가)

 

재설정할 수 없는 기기 식별자 제한

 

IMEI

Android 10(API 수준 29)에는 IMEI와 일련번호가 포함된 재설정이 불가능한 식별자에 관한 제한사항이 추가됩니다. 이러한 식별자에 액세스하려면 앱이 기기 또는 프로필 소유자 앱이거나 앱에 이동통신사 특별 권한 또는 READ_PRIVILEGED_PHONE_STATE 권한이 있어야 합니다.

이 섹션에서는 IMEI와 같은 하드웨어 ID의 대안을 제공합니다. 하드웨어 ID는 사용자가 재설정할 수 없고 기기로 범위가 한정되므로 사용하지 않는 것이 좋습니다. 대부분의 경우 앱 범위 식별자로 충분합니다.

 

MAC 주소

MAC 주소는 전역적으로 고유하며, 사용자가 재설정할 수 없고 초기화 후에도 유지됩니다. 이런 이유로 사용자 식별을 위해 MAC 주소를 사용하는 것은 대개 어떠한 형태라도 권장하지 않습니다. Android 10(API 수준 29) 이상을 실행하는 기기는 기기 소유자 앱이 아닌 모든 앱에 무작위로 지정된 MAC 주소를 보고합니다.

Android 6.0(API 수준 23)과 Android 9(API 수준 28) 사이에서 Wi-Fi 및 블루투스와 같은 로컬 기기 MAC 주소는 타사 API를 통해 사용할 수 없습니다. WifiInfo.getMacAddress() 메서드와 BluetoothAdapter.getDefaultAdapter().getAddress() 메서드는 모두 02:00:00:00:00:00을 반환합니다.

또한, Android 6.0과 Android 9 사이에서 블루투스 및 Wi-Fi 검색을 통해 사용 가능한 주변 외부 기기의 MAC 주소에 액세스하려면 다음 권한을 보유해야 합니다.

메서드/속성필요한 권한
WifiManager.getScanResults() ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION
BluetoothDevice.ACTION_FOUND ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION
BluetoothLeScanner.startScan(ScanCallback) ACCESS_FINE_LOCATION 또는 ACCESS_COARSE_LOCATION

 

고유 식별자가 필요한 상황들은 어떤 것들이 있을까?

1. 콘텐츠 접근 디바이스 수를 제한하려고 할 때

  ex) 3대의 디바이스에서만 접근가능할 때

  •   너무 쉽게 재설정할 수 있는 범위가 작은 식별자를 사용할 경우 사용자가 의도치 않게 불이익을 받을 수도 있다.(앱을 삭제했다가 다시 설치하는 경우 식별자가 변경되어 새로운 디바이스라고 인식되어 콘텐츠 접근이 막힌다던가.)

2. 부정사용 및 악의적인 디바이스  or 사용자를 제한하려고 할 때

  • 이럴 경우 디바이스 범위의 식별자 사용을 고려할 수 있으나, 악성사용자가 사용하는 디바이스는 애뮬레이터 혹은 루팅된 OS가 설치된 비정상 안드로이드 디바이스일 가능성이 높고 사용자가 쉽게 디바이스 식별자를 변경할 수도 있다. 따라서 이 때는 단말 단에서 쉽게 위조가 가능한 디바이스 식별자를 사용하는 대신, 디바이스의 무결성을 검증할 수 있는 다른 수단(ex. 구글에서 제공하는 SafetyNet Attestation API)을 활용해 먼저 디바이스 무결정 검증 후 다른 추가적인 신호를 조합해서 활용할 것을 권장한다.

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

  • 앱 구룹 범위의 식별자가 필요하다. 만일 서비스 중인 앱들이 동일 서명키로 서명된 경우 SSAID 활용가능하다. 서명기가 다른 경우  앱 자체적으로 GUID를 생상한 후, 해당 ID를 다른 앱과 공유하는 방식을 고민해 봐야함.

우리 앱은 현재 어떤 상황이며 어떠한 목적으로 고유 식별자를 필요로 하는가?

어떤 식별자가 가장 적합할까?

구글문서 : 일반적인 사용사례 및 사용하기 적합한 식별자

 

이 섹션에서는 IMEI와 같은 하드웨어 ID의 대안을 제공합니다. 하드웨어 ID는 사용자가 재설정할 수 없고 기기로 범위가 한정되므로 사용하지 않는 것이 좋습니다. 대부분의 경우 앱 범위 식별자로 충분합니다.

 

로그아웃한 사용자 환경설정 추적

사용자 계정 없이 서버에 기기별 상태를 저장하고 있는 경우입니다.

사용: 인스턴스 ID 또는 GUID

권장하는 이유

사용자가 앱을 다시 설치하여 환경설정을 재설정하는 것을 원할 수도 있으므로 재설치 후에도 정보가 지속되는 것은 권장되지 않습니다.

동일한 서명 키가 있는 앱 간에 로그아웃한 사용자 환경설정 추적

서버에 기기별 상태가 저장되며 동일한 기기에 동일한 키로 서명된 서로 다른 앱 간에 이 상태를 전송하고 있는 경우입니다.

사용: SSAID

권장하는 이유

Android 8.0(API 레벨 26) 이상에서 SSAID는 동일한 개발자 서명 키로 서명된 앱 간에 공통된 식별자를 제공합니다. 따라서 사용자가 계정에 로그인하지 않아도 이러한 앱 간에 상태를 공유할 수 있습니다.

 

로그아웃한 사용자 행동 추적

동일한 기기에서 서로 다른 앱/세션 간에 사용자 행동을 기반으로 사용자 프로필을 만든 경우입니다.

사용: 광고 ID

권장하는 이유

사용자가 ID를 재설정할 수 있으므로 Google Play 개발자 콘텐츠 정책에 따라 광고 사용 사례에는 광고 ID를 사용해야 합니다.

 

로그아웃한 사용자 또는 익명의 사용자 분석 생성

로그아웃한 사용자 또는 익명 사용자의 사용 통계와 분석을 측정하고 있는 경우입니다.

사용: 인스턴스 ID 또는 GUID(인스턴스 ID가 충분하지 않은 경우)

권장하는 이유

인스턴스 ID 또는 GUID는 이러한 ID를 생성한 앱으로 범위가 지정되므로 여러 앱 간에 사용자를 추적하는 데 식별자가 사용되는 것을 방지합니다. 또한, 사용자가 앱 데이터를 삭제하거나 앱을 다시 설치할 수 있으므로 쉽게 재설정할 수 있습니다. 인스턴스 ID와 GUID를 만드는 과정은 간단합니다.

  • 인스턴스 ID 만들기: Firebase 클라우드 메시징 가이드를 참조하세요.
  • GUID 만들기: 다음 코드 스니펫에서와 같이 앱에 로직을 구현합니다. 
        val uniqueID: String = UUID.randomUUID().toString()
        
  •  
  • Kotlin자바

수집하는 데이터가 익명이라고 사용자에게 말한 경우 PII에 연결되었을 수 있는 다른 식별자 또는 PII에 식별자를 연결하지 않아야 합니다.

또한, 앱별 분석의 해결 방법을 제공하는 모바일 앱용 Google 애널리틱스를 사용할 수도 있습니다.

 

로그아웃한 사용자 전환 추적

마케팅 전략의 성공 여부를 알아내기 위해 전환을 추적하고 있는 경우입니다.

사용: 광고 ID

권장하는 이유

광고 관련 사용 사례로, 다양한 앱에서 사용 가능한 ID가 필요할 수 있으므로 광고 ID를 사용하는 것이 가장 적절한 해결 방법입니다.

 

다양한 기기에서 여러 설치 처리

동일한 사용자를 위해 여러 기기에 앱을 설치할 때 앱의 올바른 인스턴스를 식별해야 하는 경우입니다.

사용: 인스턴스 ID 또는 GUID

권장하는 이유

인스턴스 ID는 명확히 이 용도로 설계되었습니다. ID 범위가 앱으로 제한되므로 서로 다른 앱 간의 사용자 추적에 사용될 수 없으며 앱을 다시 설치하면 재설정됩니다. 드물지만 인스턴스 ID가 충분하지 않은 경우 GUID를 사용할 수도 있습니다.

 

사기 예방: 무료 콘텐츠 제한 시행/Sybil 공격 감지

사용자가 기기에서 볼 수 있는 무료 콘텐츠(예: 기사) 수를 제한하려는 경우입니다.

사용: 인스턴스 ID 또는 GUID. Android 8.0(API 레벨 26) 이상에서는 SSAID의 범위가 앱 서명 키로 지정되므로 SSAID도 사용할 수 있습니다.

권장하는 이유

GUID 또는 인스턴스 ID를 사용하는 경우 사용자가 콘텐츠 제한을 우회하려면 앱을 다시 설치해야 하므로, 이러한 부담으로 인해 대부분의 사용자는 우회를 포기합니다. 이 ID 사용으로 충분히 보호되지 않는 경우 Android는 콘텐츠에 대한 액세스를 제한하는 데 사용할 수 있는 DRM API를 제공하며, 여기에는 APK당 식별자인 Widevine ID가 포함됩니다.

 

이동통신사 기능

앱에서 이동통신사 계정을 사용해 기기의 전화 및 문자 기능과 상호작용하고 있는 경우입니다.

사용: IMEI, IMSI, Line1

권장하는 이유

이동통신사 관련 기능에 필요한 경우 하드웨어 식별자를 활용할 수 있습니다. 예를 들어 이러한 식별자를 사용해 이동통신사 또는 SIM 슬롯 간을 전환하거나 IP(Line1의 경우) - SIM 기반 사용자 계정을 통해 SMS 메시지를 전송할 수 있습니다. 하지만 권한이 설정되지 않은 앱의 경우 계정 로그인을 사용해 서버의 사용자 기기 정보를 검색하는 것이 좋습니다. 이러한 이유 중 하나는 Android 6.0(API 레벨 23) 이상에서는 런타임 권한을 통해서만 이 식별자를 사용할 수 있다는 점입니다. 사용자가 이 권한을 해제할 수 있으므로 앱에서 이러한 예외를 매끄럽게 처리해야 합니다.

 

악용 감지: 봇과 DDoS 공격 식별

백엔드 서비스를 공격하는 여러 가짜 기기를 감지하려는 경우입니다.

사용: SafetyNet API

권장하는 이유

격리된 식별자는 기기의 진위를 나타내기 어렵습니다. 요청하는 기기의 무결성을 확인하는 SafetyNet API의 attest() 메서드를 사용하면 (다른 기기를 스푸핑하는 에뮬레이터 또는 기타 코드가 아닌) 진짜 Android 기기에서 오는 요청을 확인할 수 있습니다. 자세한 내용은 SafetyNet API 문서를 참조하세요.

 

사기 및 악용 감지: 도난당한 중요한 사용자 인증 정보 감지

한 대의 기기가 도난당한 중요한 사용자 인증 정보로 여러 번 사용되고 있는지(예: 사기 결제) 감지하려는 경우입니다.

사용: 특성상 사기를 방지하려면 시간이 지남에 따라 변경할 수 있는 독점 신호가 필요하며, 이 내용은 이 문서의 범위를 벗어납니다. 그러나 IMEI 및 IMSI와 같은 하드웨어 식별자는 루팅된 기기나 에뮬레이션된 기기에서 쉽게 수정할 수 있으므로 신뢰할 수 있는 사기 지표는 아닙니다.

 

 

 

 

 

 

 

 

 

참고사이트

더보기