이 페이지에서는 Android 기기에 설치된 APK가 신고자 모델에서 이루어진 주장과 일치하는지 확인하는 다양한 방법을 간략하게 설명합니다. 여기에는 문제의 APK를 기기에서 가져오고, 코드 무결성을 확인하고, 추출된 아티팩트에 로그 포함 증명을 실행하는 작업이 포함됩니다.
인증 프로세스
투명성 로그는 해시로 구성된 Merkle 트리로 구현됩니다. 리프 노드에는 데이터가 포함되고 상위 노드에는 하위 노드의 해시가 포함됩니다.
기본적으로 Merkle 트리에서 두 가지 계산이 실행되어 투명성 로그의 변조 방지 속성을 확인합니다. 포함 증명과 일관성 증명입니다. 전자는 로그에 특정 APK 버전에 해당하는 항목이 포함되어 있음을 증명합니다. 로그 항목에는 해당 APK에서 가져올 수 있는 JSON 웹 토큰(JWT) 형식의 코드 서명 토큰의 SHA256 다이제스트인 해시가 포함됩니다. 후자는 새 항목이 트리에 추가될 때 새 체크포인트가 이전 버전의 트리와 (암호화 방식으로) 일관됨을 증명합니다.
적용되는 APK를 확인하려면 확인된 체크포인트를 기반으로 포함 증명 테스트를 실행합니다. 표준화된 확인 프로토콜을 사용하여 이 로그를 공개 확인 네트워크 와 통합할 계획입니다. 이렇게 하면 로그의 일관성을 보장하는 확인된 체크포인트가 제공됩니다.
기기에 있는 APK가 신고자 모델에서 이루어진 주장과 일치하는지 확인하려면 아래 글을 참고하세요.
포함 증명
Android 사용자는 먼저 APK와 관련 메타데이터를 추출한 다음 재계산된 루트 해시를 게시된 체크포인트에 포함된 루트 해시와 비교하여 기기의 적용되는 APK가 로그에 있는지 확인할 수 있습니다. 일치하는 경우 Android 사용자는 위협 모델에 설명된 일부 보호를 받을 수 있습니다.
로그에서 APK 포함을 확인하는 방법
앞서 설명한 대로 현재 적용되는 APK 목록은 개요 페이지에 나열되어 있습니다.
인증 전제 조건
아티팩트 (펌웨어 또는 APK)가 주장에 부합하는지 확인하기 전에 네트워크에 연결된 컴퓨터에서 다음 도구를 사용할 수 있는지 확인하세요. 인증 대상에 따라 일부 도구가 필요하지 않을 수도 있습니다.
Golang
인증 도구 는 Go로 작성됩니다. 빌드하려면 Go 사이트에서 Go 1.24 이상을 설치하세요. Go 사이트
Android 디버그 브리지 (ADB)
ADB는 Android 기기와 통신하여 이미지를 검사하거나
APK를 추출하는 도구로, Android SDK 플랫폼 도구 웹사이트에서 사용할 수 있습니다.
포함 증명 확인자
포함 증명 확인자는 투명성 로그를 쿼리하고 아티팩트가 로그에 포함되어 있는지 출력하는 Go 모듈입니다.
android-binary-transparency GitHub 저장소에 게시됩니다.
https://github.com/android/android-binary-transparency/tree/main
AOSP avb 저장소를 클론하려면 다음을 실행하세요.
computer:~$ git clone https://android.googlesource.com/platform/external/avb
android-binary-transparency GitHub 저장소를 클론하려면 다음을 실행하세요.
computer:~$ git clone https://github.com/android/android-binary-transparency
AAPT2
AAPT2 (Android Asset Packaging Tool)는 Android 앱의 리소스를 컴파일하고 패키징하는 데 사용되는 빌드 도구입니다. Android SDK 빌드 도구 버전 26.0.2 이상에서 독립형 도구로 찾을 수 있습니다.
bundletool
bundletool은 Android App Bundle (AAB)을 빌드하는 데 사용되는 도구입니다. APK 코드 서명을 확인하는 데 사용할 수도 있습니다.
GitHub에서 다운로드할 수 있습니다.
wget 또는 curl
wget 및 curl 은 인터넷에서 파일을 가져오거나 다운로드하는 데 사용할 수 있는 도구입니다. 인증 스크립트가 이러한 도구를 사용할 수 있으므로 이러한 도구 중 하나를 설치해야 합니다.
Avbtool
avbtool
은 출고 시 이미지의 VBMeta 다이제스트를 계산하고
바이너리를 인증하는 데 사용됩니다.
포함 증명 확인자
섹션에 표시된 대로 avb 저장소를 클론한 후 클론된 avb 디렉터리 내에서 avbtool.py를 찾을 수 있습니다.
이 디렉터리를 $PATH 환경 변수에 추가해야 합니다.
computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL
Fbpacktool
fbpacktool
은 Pixel의
bootloader.img에서 개별 구성요소를 압축 해제하는 데 사용되는 Python 스크립트입니다.
APK를 인증하는 경우에는 필요하지 않습니다.
이 도구는 avbtool.py가 인증에 필요한 이미지를 검색할 수 있도록 하므로 중요합니다.
이 도구를 사용하려면 다음 세 가지 Python 스크립트를
avbtool.py가 있는 디렉터리에 다운로드하고,
fbpacktool.py를 실행 파일로 만들고,
편의를 위해 fbpacktool.py에 fbpacktool이라는 심볼릭 링크를 만들어야 합니다.
wget이 있는 경우:
computer:dir_to_avbtool$ wget https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool
curl이 있는 경우:
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool
OpenSSL
openssl은 인증 워크플로에서 터미널을 사용하여 다양한 암호화 작업을 실행하는 데 도움이 됩니다. 시스템에 설치되어 있는지 확인하세요. 다음 명령어를 실행하고 반환된 결과가 비어 있지 않은지 확인하여 터미널에서 확인할 수 있습니다.
computer:~$ which openssl
/usr/bin/openssl
인증을 위한 페이로드 구성
주장에 따라 기기에서 추출한 APK를 인증하려면 APK에서 파생된 정보로 로그 페이로드를 구성해야 합니다.
시작하기 전에 기기에서 adb 디버깅을 사용 설정하여 기기에서 adb를 사용할 수 있는지 확인하세요.
그런 다음 기기에 APK가 설치된 위치를 찾습니다. 이 가이드에서는 Android 시스템 키 확인자 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 시스템 키 확인자 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는 궁극적으로 특수한 종류의 ZIP 파일이므로 다운로드한 APK의 패키지 이름을 가져와서 인증하려면 먼저 APK의 압축을 풀어야 합니다.
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
이 단계에서는 APK를 구성하는 모든 파일의 압축을 풉니다. 패키지 이름과
버전은 일반적으로 AndroidManifest.xml이라는 파일에 있는 APK의
manifest
에서 찾을 수 있습니다.
하지만 가져온 manifest 파일은 사람이 읽을 수 없는 바이너리 형식입니다.
바이너리 XML을 사람이 읽을 수 있는 형식으로 변환하기 위해 이전에 설치한
aapt2 도구 (전제 조건
섹션에서 설치해야 함)를 사용합니다.
computer:/tmp/testdir$ aapt2 dump badging ./contactkeys_candidate.apk
package: name='com.google.android.contactkeys' versionCode='7805' versionName='1.219.791156583' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
위의 출력에서 이제 이 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
이제 bundletool의 check-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_1p_code
확인자는 해당하는 체크포인트와 로그 콘텐츠 (tile 디렉터리에 있음)를 사용하여 APK 페이로드가 투명성 로그에 있는지 확인하고 Google에서 게시했는지 확인합니다.
명령어의 출력은 stdout에 기록됩니다.
- 패키지의 코드가 로그에 포함된 경우
OK. inclusion check success! - 포함되지 않은 경우
FAILURE