Google 시스템 서비스 APK 투명성 전체 인증

이 페이지에서는 Android 기기에 설치된 APK가 신고자 모델에서 제기된 소유권 주장과 일치하는지 확인하는 다양한 방법을 설명합니다. 이를 위해서는 기기에서 문제의 APK를 가져오고, 코드 무결성을 확인하고, 추출된 아티팩트에서 로그 포함 증명을 실행해야 합니다.

인증 절차

투명성 로그는 해시로 구성된 Merkle 트리로 구현됩니다. 리프 노드에는 데이터가 포함되고 상위 노드에는 하위 노드의 해시가 포함됩니다.

기본적으로 투명성 로그의 변조 방지 속성을 확인하기 위해 Merkle 트리에서 두 가지 계산(포함 증명 및 일관성 증명)이 실행됩니다. 전자는 로그에 특정 APK 버전에 해당하는 항목이 포함되어 있음을 증명합니다. 로그 항목에는 JSON 웹 토큰(JWT) 형식의 코드 서명 토큰의 SHA256 다이제스트인 해시가 포함되며, 이 해시는 상응하는 APK에서 가져올 수 있습니다. 후자는 새 항목이 트리에 추가될 때 새 체크포인트가 이전 버전의 트리와 (암호화적으로) 일치함을 증명합니다.

적용 범위가 지정된 APK를 확인하려면 목격된 체크포인트를 기반으로 포함 증거 테스트를 실행합니다. 표준화된 증인 프로토콜을 사용하여 이 로그를 공개 증인 네트워크와 통합할 계획입니다. 이렇게 하면 로그의 일관성을 보장하는 목격된 체크포인트가 제공됩니다.

기기에 있는 APK가 신고자 모델에서 제기된 주장을 준수하는지 확인하려면 아래 문서를 참고하세요.

포함 증거

Android 사용자는 먼저 APK와 관련 메타데이터를 추출한 다음 재계산된 루트 해시를 게시된 체크포인트에 포함된 루트 해시와 비교하여 기기의 적용 범위가 지정된 APK가 로그에 있는지 확인할 수 있습니다. 일치하는 경우 Android 사용자는 위협 모델에 설명된 일부 보호 기능을 사용할 수 있습니다.

로그에 APK가 포함되어 있는지 확인하는 방법

앞서 설명한 대로 현재 적용되는 APK 목록은 개요 페이지에 나와 있습니다.

인증 전제 조건

방금 기기에서 추출한 APK가 Google의 주장과 일치하는지 확인하기 전에 네트워크에 연결된 컴퓨터에서 다음 도구를 설치해야 합니다.

Android 디버그 브리지(ADB)

ADB는 Android 기기와 통신하는 도구로, Android SDK 플랫폼 도구 웹사이트에서 사용할 수 있습니다.

bundletool

bundletool은 Android App Bundle (AAB)을 빌드하는 데 사용되는 도구입니다. AAB를 기기에 설치할 수 있는 APK로 변환하는 데도 사용할 수 있습니다. GitHub에서 다운로드할 수 있습니다.

Androguard

Androguard는 APK를 분석하는 데 사용되는 도구 모음입니다. Androguard 웹사이트에서 다운로드하여 설치할 수 있습니다.

포함 증거 검증자

이 모듈은 Android 오픈소스 프로젝트 (AOSP) 내의 avb라는 Git 저장소에 게시된 Go 모듈입니다. Google 시스템 서비스 APK 투명성 로그를 쿼리할 수 있으며 패키지가 로그에 포함되어 있는지 출력합니다. 이 방법을 사용하는 예는 이후 섹션에서 확인할 수 있습니다.

이 도구를 다운로드하려면 먼저 avb 저장소를 클론해야 합니다.

computer:~$ git clone https://android.googlesource.com/platform/external/avb

검증자의 소스 코드는 avb 저장소 내 tools/transparency/verify에서 확인할 수 있습니다.

확인을 위한 페이로드 구성

Google의 주장에 따라 기기에서 추출한 APK가 맞는지 확인하려면 APK에서 파생된 정보로 로그 페이로드를 구성해야 합니다.

시작하기 전에 기기에서 adb 디버깅을 사용 설정하여 기기에서 adb를 사용할 수 있는지 확인하세요.

그런 다음 기기에 APK가 설치된 위치를 찾습니다. 이 가이드에서는 Android System Key Verifier APK(com.google.android.contactkeys)를 작동하는 예시로 사용합니다.

computer:~$ adb shell pm list packages -f | grep contactkeys
package:/data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk=com.google.android.contactkeys

Android System Key Verifier APK가 기기에 설치되어 있으면 위의 명령어는 기기에 APK가 설치된 위치를 나타내는 경로를 반환합니다. 그렇지 않으면 출력이 표시되지 않습니다.

그런 다음 다음 명령어를 사용하여 Android 기기에서 작업 중인 컴퓨터로 APK를 다운로드합니다. 기기의 실제 위치와 APK 파일 이름은 다를 수 있습니다.

computer:~$ mkdir -p /tmp/testdir && cd /tmp/testdir
computer:/tmp/testdir$ adb pull /data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk ./contactkeys_candidate.apk

방금 다운로드한 APK의 패키지 이름을 가져와 확인하려면 먼저 APK의 압축을 풀어야 합니다. APK는 궁극적으로 특별한 종류의 ZIP 파일이므로

computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/

이 단계에서는 APK를 구성하는 모든 파일을 압축해제합니다. 패키지 이름과 버전은 APK의 매니페스트에서 확인할 수 있으며, 일반적으로 AndroidManifest.xml라는 파일에 있습니다.

그러나 가져온 매니페스트 파일은 사람이 읽을 수 없는 바이너리 형식입니다. 바이너리 XML을 사람이 읽을 수 있는 형식으로 변환하기 위해 androguard 모음의 axml 도구를 사용합니다 (기본 요건 섹션에 설치해야 함).

computer:/tmp/testdir$ androguard axml extracted/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1413" android:versionName="1.48.688082145" android:compileSdkVersion="35" android:compileSdkVersionCodename="VanillaIceCream" android:requiredSplitTypes="" android:splitTypes="" package="com.google.android.contactkeys" platformBuildVersionCode="35" platformBuildVersionName="VanillaIceCream">

위의 출력에서 이 APK의 패키지 이름은 com.google.android.contactkeys이고 버전 번호 (versionCode)는 1413임을 알 수 있습니다.

이제 APK 내에서 코드 투명성 서명을 검색합니다. APK에서 추출한 다른 파일 중 META-INF 폴더에 포함된 code_transparency_signed.jwt라는 파일입니다.

computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11  code_transparency_signed.jwt

이제 이 해시 문자열을 통해 로그 콘텐츠 섹션에 설명된 형식에 따라 로그 페이로드를 조합하는 데 필요한 모든 정보를 갖게 되었습니다. 이 예시에서 상응하는 로그 페이로드는 다음과 같습니다.

1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143

패키지 버전 뒤의 줄바꿈 문자도 확인합니다.

콘텐츠를 payload.txt와 같은 파일에 저장할 수 있습니다. 이는 나중에 포함 증거 테스트를 실행할 때 유용합니다.

APK 코드 서명의 진위 여부 확인

이제 APK에 삽입된 코드 서명 토큰의 진위를 확인해야 합니다. 이를 위해 bundletool와 처음에 서명하는 데 사용된 키 쌍의 공개 키를 사용합니다. 각 APK의 각 섹션 내에 게시됩니다. 공개 키 인증서(예: Android 시스템 키 검사기)를 signing_cert_pubkey.pem라는 파일에 저장했다고 가정하고 아래 가이드를 따라 코드 서명 확인을 실행합니다.

먼저 zip 보관 파일을 만들고 후보 APK를 zip 보관 파일에 추가해야 합니다.

computer:/tmp/testdir$ zip -u test.zip contactkeys_candidate.apk
        zip warning: test.zip not found or empty
  adding: contactkeys_candidate.apk (deflated 58%)

computer:/tmp/testdir$ file test.zip
test.zip: Zip archive data, at least v2.0 to extract, compression method=deflate

이제 bundletoolcheck-transparency 명령어를 사용하여 후보 APK에 삽입된 코드 서명이 게시된 코드 서명과 일치하는지 확인할 수 있습니다.

computer:/tmp/testdir$ java -jar BUNDLETOOL_INSTALL_PATH/bundletool-all-version.jar check-transparency \
  --mode=apk \
  --apk-zip=test.zip \
  --transparency-key-certificate=signing_cert_pubkey.pem

APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): D9 E1 73 5B 2A 39 51 27 3A 87 35 B7 66 9E F1 9E F5 3A F1 C1 27 5C BA 31 39 3C 18 40 8B 03 79 D0
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.

위 명령어의 출력에서 코드 투명성 서명코드 투명성이 모두 확인되었다고 표시되어야 합니다. 그렇지 않은 경우(예: Code transparency verification failed because the provided public key certificate does not match the transparency file와 같은 출력이 표시되는 경우) 해당 APK의 코드 무결성이 손상되었을 수 있으므로 APK를 신뢰해서는 안 됩니다. 올바른 공개 키 인증서와 대조하여 인증하고 있는지 다시 확인하세요. 그 밖의 모든 항목이 확인되면 검사 중인 APK의 코드 서명 진위성이 확인된 것입니다.

패키지 포함 확인 (포함 증거)

앞서 구성한 페이로드를 사용하여 이제 해당 패키지가 투명성 로그에 포함되었는지 테스트할 수 있습니다.

포함 증명 도구가 Android 오픈소스 프로젝트 내 avb 저장소에 게시되었습니다. 실행하려면 다음 단계를 따르세요.

computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_system_apk

검사기는 상응하는 체크포인트와 로그 콘텐츠 (타일 디렉터리에 있음)를 사용하여 APK 페이로드가 투명성 로그에 있는지 확인하여 Google에서 실제로 게시했는지 확인합니다.

명령어의 출력은 stdout에 기록됩니다.

  • OK. inclusion check success! 패키지의 코드가 로그에 포함된 경우
  • FAILURE를 입력합니다.