개발자를 위한 안드로이드 #7
이 포스트는 안드로이드 Q 베타 2 패치 버전을 기준으로 작성되었습니다. Q 정식 버전에서는 기능 및 API가 변경될 수 있습니다. 기능에 관한 소감이나 의견은 개인적인 의견으로 회사의 공식 의견과는 다를 수 있습니다. 본 포스트는 안드로이드 MediaDrm API를 이용해, 기기 초기화 후에도 유지되는 고유 식별자를 얻는 방법을 다룹니다.
이전 포스트에서 정리한 것처럼, 안드로이드 Q에서는 IMEI, MEID, Build.Serial 등 사용자가 재설정할 수 없는 식별자를 사용할 수 없습니다. 예외적으로 허용되는 두 가지 케이스가 있지만, 아래 정리한 것처럼, 일반적인 앱 개발자에게는 해당되지 않을 것으로 보입니다.
1.READ_PRIVILEGED_PHONE_STATE 권한 사용하기
이 권한은 기본적으로 통신사에서만 사용할 수 있는 권한입니다. UICC (일반적으로 심카드)에 저장된 서명으로 서명된 앱이나, 시스템에 미리 정의된 전화 관련 소수의 앱만이 사용 가능한 권한으로 보입니다. 그 외 앱이 사용자 동의 등 다른 방법으로 READ_PRIVILEGED_PHONE_STATE 권한을 획득할 수 있는 방법은 없습니다.
2. Device Administration 앱 개발하기
안드로이드 엔터프라이즈 환경에서는 특정 정책을 해당 디바이스에 강제하는 Device Policy Client 앱이 필요합니다. 이런 앱을 Profile Owner 혹은 Device Owner 앱이라고 합니다. 만일, 안드로이드 엔터프라이즈 솔루션 성격의 앱을 만들고 있다면, 기존처럼 READ_PHONE_STATE 권한으로 IMEI 등의 고유 식별자를 기존처럼 사용할 수 있습니다. 다만, 그 외 일반적인 성격의 앱이 Profile Owner 혹은 Device Owner 앱으로 동작할 수 있는 방법은 없습니다.
고유 식별자에 모범 사례 문서를 살펴보면 재설정할 수 없는 식별자 대신 사용할 수 있는 여러 대안들이 용도별로 잘 설명되어 있습니다 (영문 버전으로 확인하시면 더 많은 내용을 확인하실 수 있습니다). 그중 광고 ID, GUID, Instance ID, SSAID 등 익숙한 이름과 함께 Widevine ID가 언급됩니다.
Android provides a DRM API, which can be used to limit access to content, includes a per-APK identifier, the Widevine ID.
DRM API를 통해 Widevine ID를 APK 범위 식별자로 사용할 수 있다고 설명되었지만, 어떻게 이를 활용할 수 있는지 구체적인 내용은 빠져있습니다. 지금까지 사용해본 적이 없는 식별자라, 이 기회에 어떻게 사용할 수 있는 식별자인지 사용 방법을 조사 및 정리해보았습니다.
기본적으로 안드로이드는 확장 가능한 DRM 프레임워크를 제공합니다 (4.3 버전 이상). 각 DRM 모듈은 플러그인 방식으로 적용되고, 앱에서는 공통 인터페이스를 통해 임의의 DRM 모듈을 쉽게 사용할 수 있습니다. 구글에서는 DRM 프레임워크가 널리 사용되고 개발자들이 손쉽게 DRM 콘텐츠를 재생할 수 있도록 무료로 DRM 모듈을 제공하고 있습니다. 바로 Widevine이 무료로 제공되는 DRM 모듈 이름입니다. 구글 플레이를 탑재한 디바이스의 경우 Widevine 모듈을 꼭 포함하고 있어야 합니다.
DRM 모듈은 올바른 권리가 있는 앱과 디바이스만 콘텐츠를 재생할 수 있도록 디바이스 고유 식별자 정보를 키 값으로 사용합니다. 각각의 DRM 모듈은 자기 나름의 고유 식별자가 필요하고, 그중 Widevine 모듈에서 사용하는 고유 식별자가 바로 Widevine ID입니다.
Widevine ID의 가장 큰 장점은 두 가지입니다. 먼저, 사용하는 데는 별도의 사용자 권한이 필요하지 않습니다. 두 번째로, 디바이스를 초기화하는 경우에도 식별자 값이 동일하게 유지됩니다. 다만, 사용할 수 있는 안드로이드 버전 및 디바이스의 종류가 제한적입니다. 예를 들어 4.3 이전 디바이스나, 구글 플레이를 탑재하지 않은 디바이스에서는 사용이 불가능할 수도 있습니다. 또한, Widevine ID는 안드로이드 8.0 미만 버전에서는 식별자의 범위가 전체 디바이스 범위로 사용에 부담이 있었습니다. 안드로이드 O 이후부터는 범위가 줄어들어 패키지 이름 범위 (앱 서명이 달라져도 패키지 명이 같으면 동일한 값이 반환됩니다)를 갖습니다. 다른 주요 고유 식별자와 특성을 비교해보면 다음과 같습니다.
원칙적으로 수명이 긴 고유 식별자가 필요한 경우 SSAID를 사용하는 것이 권장됩니다. SSAID는 모든 안드로이드 디바이스에서 사용 가능하며, 사용자가 재설정 가능 한 만큼, 덜 민감한 개인 정보로 여겨질 수 있습니다. 다만, 특정 사용자 시나리오에서는 (예를 들어 악성 사용자를 영구적으로 접근 금지시키거나, 기기마다 한 번만 제공하는 프로모션 등) 기기 초기화 후에도 유지되는 식별자가 필요할 수 있고, 이 경우에는 MediaDrm API를 통한 WidevineID 사용을 고려해볼 수 있을 것 같습니다.
이제 본론입니다. MediaDrm API를 통해 어떻게 Widevine ID를 가져올 수 있는지 코드를 살펴보겠습니다 (Brunch가 복붙을 지원하지 않는 만큼, 별도 gist를 만들어 두었습니다)
코드 자체는 특별한 내용이 없습니다. MediaDrm 클래스를 통해 Widevine DRM 모듈을 불러온 후, 디바이스 고유 식별자를 가져옵니다. 다만, 몇 가지 주의할 점이 있습니다.
WIDEVINE_UUID 값은 Widevine 모듈을 나타내는 고유한 GUID 값입니다. 각 DRM 모듈은 글로벌 범위에서 유일한 GUID 값을 갖고 있습니다. 안드로이드에서 대표적으로 사용되는 DRM 모듈의 GUID 값은 ExoPlayer 소스 코드를 참고하면 쉽게 확인할 수 있습니다. 한 번쯤 이름은 들어봤을 법한 DRM 모듈들의 UUID 값은 다음과 같습니다.
CLEARKEY - UUID(0xE2719D58A985B3C9L, 0x781AB030AF78D30EL)
PLAYREADY - UUID(0x9A04F07998404286L, 0xAB92E65BE0885F95L)
WIDEVINE - UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL)
WidevineID를 가져오기 위해서는 MediaDRM 객체를 생성해야 하는데, 이 작업에 비교적 오랜 시간이 걸립니다. 에뮬레이터로 테스트할 때는 약 400ms 정도가 소요되었고, 픽셀 3에서 테스트할 때는 약 200ms 정도가 걸렸습니다. 따라서, WidevineID를 가져올 때는 메인 스레드가 아닌 별도의 비동기 작업이 필요할 것으로 보입니다.
마지막으로 Widevine DRM은 L1, L2, L3 세 단계의 보안 레벨을 갖고 있습니다. L1은 가장 높은 수준의 보안이며 L3가 가장 낮은 단계입니다. 안드로이드 디바이스는 L1 혹은 L3 수준의 Widevine DRM을 갖게 됩니다. 이때, Widevine DRM L1을 만족하는 디바이스 상에서만 기기 초기화 후에도 Widevine ID 값이 동일하게 유지됩니다. 아주 정확한 동작 방식은 확인하기 어렵지만, 기본적으로 L1 단계에서만, 전체 DRM 처리가 안드로이드 TEE(Trusted Execution Environment) 환경에서 이루어지고, 이 경우에만 디바이스 고유키에 접근하는 것이 가능한 것으로 보입니다. 넷플릭스 등 주요 콘텐츠 앱들이 Widevine DRM L1 인증 디바이스에서만 HD 콘텐츠 재생을 허용하기 때문에, 대부분의 주요 단말 등은 Widevine DRM L1을 지원하고 있습니다. 다만, 구형 단말이나 일부 중소 제조사 태블릿, 스마트폰은 L3 만 지원하는 경우도 있을 수 있습니다. 이를 위해, Widevine ID 값을 사용하기 전에는 해당 디바이스의 Widevine ID 보안 수준을 확인할 필요가 있습니다. 보안 수준은 'securityLevel' 속성 값을 통해 확인할 수 있습니다 (link).
안드로이드 Q 베타 2 버전 공개를 기념하여 기존 IMEI 등 고유 식별자 대신 사용할 수 있는 값 중 Widevine ID를 사용하는 방법과 주의점을 정리해보았습니다. 다만, 지원되는 디바이스나 제약 조건이 있고 취급에 각별한 주의가 필요한 식별자인 만큼, 일반적인 경우 광고 ID 혹은 SSAID를 대안으로 선택하는 것이 더 나은 방법으로 생각됩니다. 그럼에도 특정 디바이스의 콘텐츠 접근을 영구적으로 막을 필요가 있거나 (악성 유저 원천 차단), 기기별로 혜택을 제공하는 프로모션 등을 진행하는 경우 제한적으로 Widevine ID 사용을 고려해볼 수 있을 것 같습니다.
이번 포스트에서 다룬 고유 식별자 관련 내용 외에도, 개발자 주의가 예상되는 안드로이드 Q의 변경 사항을 정리해 '개발자를 위한 안드로이드 Q 정리'라는 브런치 매거진으로 발행하고 있습니다. 안드로이드 Q 버전이 정식 출시될 때까지, '개발자를 위한 안드로이드 Q 정리 매거진'에 많은 관심 부탁드립니다 : ) 이어질 다음 포스트에서는 드디어 개인 정보 보호 관련된 주제에서 벗어나, Q에서 새롭게 추가된 여러 기능들 중 Sharing Shortcut API에 관해 정리해볼 계획입니다.