Trang này trình bày nhiều phương thức để đảm bảo rằng tệp APK được cài đặt trên thiết bị Android của bạn tương ứng với thông báo xác nhận quyền sở hữu đã đưa ra trong Mô hình bên xác nhận quyền sở hữu. Thao tác này bao gồm việc lấy tệp APK có liên quan từ thiết bị, kiểm tra tính toàn vẹn của mã và thực hiện bằng chứng đưa nhật ký vào cấu phần phần mềm đã trích xuất.
Quy trình xác minh
Nhật ký minh bạch được triển khai bằng cây Merkle bao gồm các hàm băm. Nút lá chứa dữ liệu và nút mẹ chứa hàm băm của các nút con.
Về cơ bản, hai phép tính được thực hiện trên cây Merkle để xác minh thuộc tính phát hiện hành vi can thiệp của nhật ký minh bạch: bằng chứng bao gồm và bằng chứng về tính nhất quán. Trường hợp trước chứng minh rằng nhật ký bao gồm một mục tương ứng với một phiên bản APK cụ thể. Mục nhập nhật ký bao gồm một hàm băm, là chuỗi đại diện SHA256 của mã thông báo chữ ký mã ở dạng Mã thông báo web JSON (JWT). Bạn có thể lấy mã thông báo này từ các tệp APK tương ứng. Trường hợp sau chứng minh rằng khi các mục mới được thêm vào cây, điểm kiểm tra mới sẽ nhất quán (theo thuật toán mã hoá) với phiên bản cây trước đó.
Để xác minh một APK được bảo vệ, hãy thực hiện kiểm thử bằng chứng về việc đưa vào dựa trên điểm kiểm tra được chứng kiến. Xin lưu ý rằng chúng tôi dự định tích hợp nhật ký này với một mạng lưới nhân chứng công khai bằng cách sử dụng một giao thức nhân chứng được chuẩn hoá. Thao tác này sẽ cung cấp một điểm kiểm tra được chứng kiến, đảm bảo tính nhất quán của nhật ký.
Nếu bạn muốn tự tin rằng tệp APK trên thiết bị của mình tuân thủ nội dung xác nhận quyền sở hữu được đưa ra trong mô hình của bên xác nhận quyền sở hữu, hãy tham khảo nội dung viết dưới đây.
Bằng chứng về việc đưa vào
Người dùng Android có thể kiểm tra để đảm bảo rằng một tệp APK được bảo vệ trên thiết bị của họ có trong nhật ký bằng cách trích xuất tệp APK và siêu dữ liệu liên quan của tệp APK đó, sau đó so sánh hàm băm gốc được tính toán lại với hàm băm gốc có trong điểm kiểm tra đã xuất bản. Nếu khớp, người dùng Android có thể yên tâm về một số biện pháp bảo vệ được mô tả trong Mô hình mối đe doạ.
Cách xác minh việc đưa APK vào nhật ký
Như đã mô tả trước đó, bạn có thể tìm thấy danh sách các tệp APK hiện được đề cập trong trang Tổng quan.
Điều kiện tiên quyết để xác minh
Trước khi tiếp tục xác minh rằng tệp APK mà bạn vừa trích xuất từ thiết bị của mình có tuân thủ tuyên bố của chúng tôi hay không, bạn cần cài đặt các công cụ sau từ một máy tính có kết nối mạng.
Cầu gỡ lỗi Android (ADB)
ADB
là một công cụ giao tiếp với thiết bị Android, có trên trang web của Bộ công cụ nền tảng SDK Android.
bundletool
bundletool
là một công cụ dùng để tạo Android App Bundle (AAB). Bạn cũng có thể sử dụng công cụ này để chuyển đổi AAB thành các tệp APK có thể cài đặt trên thiết bị.
Bạn có thể tải xuống từ GitHub.
Androguard
Androguard là một tập hợp các công cụ dùng để phân tích tệp APK. Bạn có thể tải xuống và cài đặt công cụ này từ trang web của Androguard.
Trình xác minh bằng chứng về sự bao gồm
Đây là mô-đun Go mà chúng tôi đã phát hành trong kho lưu trữ git trong Dự án nguồn mở Android (AOSP) có tên là avb
.
Công cụ này có thể truy vấn nhật ký minh bạch về APK của Dịch vụ hệ thống của Google và cho biết liệu một gói có nằm trong nhật ký hay không.
Bạn có thể xem ví dụ về cách sử dụng tính năng này trong một phần sau.
Để tải công cụ này xuống, trước tiên, bạn phải nhân bản kho lưu trữ avb
.
computer:~$ git clone https://android.googlesource.com/platform/external/avb
Bạn có thể tìm thấy mã nguồn của trình xác minh trong tools/transparency/verify
trong kho lưu trữ avb
.
Tạo tải trọng để xác minh
Để xác minh rằng tệp APK mà bạn đã trích xuất từ thiết bị theo tuyên bố của chúng tôi, bạn phải tạo một tải trọng nhật ký từ thông tin lấy từ tệp APK đó.
Trước khi bắt đầu, hãy đảm bảo rằng bạn có thể sử dụng adb
trên thiết bị bằng cách bật tính năng gỡ lỗi adb trên thiết bị.
Sau đó, hãy tìm vị trí cài đặt APK trên thiết bị của bạn. Trong hướng dẫn này, chúng ta sẽ sử dụng tệp APK Trình xác minh khoá hệ thống Android (com.google.android.contactkeys) làm ví dụ thực tế.
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
Nếu APK Trình xác minh khoá hệ thống Android được cài đặt trên thiết bị, thì lệnh ở trên sẽ trả về một đường dẫn cho biết vị trí cài đặt tệp APK đó trên thiết bị. Nếu không, bạn sẽ không thấy kết quả nào.
Sau đó, hãy tải tệp APK từ thiết bị Android xuống máy tính bạn đang sử dụng bằng lệnh sau (lưu ý rằng vị trí thực tế và tên tệp APK trên thiết bị của bạn có thể khác nhau):
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
Để lấy và xác minh tên gói của tệp APK bạn vừa tải xuống, trước tiên, bạn cần giải nén tệp APK, vì APK cuối cùng là một loại tệp ZIP đặc biệt.
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
Bước này sẽ giải nén tất cả các tệp tạo nên tệp APK. Bạn có thể tìm thấy tên gói và phiên bản trong tệp kê khai của tệp APK, thường nằm trong tệp có tên AndroidManifest.xml
.
Tuy nhiên, tệp kê khai thu được ở dạng nhị phân, không phải dạng văn bản mà con người có thể đọc được. Để chuyển đổi tệp XML nhị phân thành một dạng mà con người có thể đọc được, chúng ta sử dụng công cụ axml
từ bộ androguard
(bắt buộc phải cài đặt trong phần điều kiện tiên quyết).
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">
Từ kết quả ở trên, chúng ta có thể chắc chắn rằng tên gói của tệp APK này là com.google.android.contactkeys
và số phiên bản (versionCode) là 1413
.
Bây giờ, chúng ta sẽ tìm chữ ký tính minh bạch của mã trong tệp APK. Đó phải là một tệp có tên code_transparency_signed.jwt
nằm trong thư mục META-INF
cùng với các tệp đã trích xuất khác từ tệp APK.
computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11 code_transparency_signed.jwt
Với chuỗi băm này, chúng ta hiện có mọi thông tin cần thiết để ghép một tải trọng nhật ký theo định dạng được mô tả trong phần Nội dung nhật ký. Trong ví dụ này, tải trọng nhật ký tương ứng sẽ có dạng như sau:
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143
Ngoài ra, hãy lưu ý ký tự dòng mới sau phiên bản gói.
Bạn có thể lưu nội dung vào một tệp, chẳng hạn như payload.txt
. Điều này sẽ hữu ích khi thực hiện kiểm thử bằng chứng bao gồm sau này.
Xác minh tính xác thực của chữ ký mã APK
Bây giờ, chúng ta nên xác minh tính xác thực của mã thông báo chữ ký mã được nhúng trong tệp APK. Để làm việc này, chúng ta sử dụng bundletool
và khoá công khai của cặp khoá đã được dùng để ký tệp đó ngay từ đầu. Các tệp này được phát hành trong từng phần của tệp APK tương ứng. Giả sử bạn đã lưu chứng chỉ khoá công khai (ví dụ: cho Trình xác minh khoá hệ thống Android) vào một tệp có tên signing_cert_pubkey.pem
, hãy làm theo hướng dẫn bên dưới để xác minh chữ ký mã.
Trước tiên, bạn nên tạo một tệp lưu trữ zip và thêm APK đề xuất vào tệp lưu trữ 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
Bây giờ, chúng ta đã sẵn sàng sử dụng lệnh check-transparency
của bundletool
để xác minh xem chữ ký mã được nhúng trong APK đề xuất có khớp với chữ ký đã xuất bản hay không.
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.
Bạn cần đảm bảo rằng kết quả của lệnh ở trên cho biết cả chữ ký tính minh bạch của mã và tính minh bạch của mã đều được xác minh.
Nếu không, ví dụ: nếu bạn thấy kết quả như Code transparency verification failed because the provided public key
certificate does not match the transparency file
, thì điều này có nghĩa là tính toàn vẹn của mã của APK có liên quan có thể bị xâm phạm và bạn không nên tin tưởng APK đó.
Hãy nhớ kiểm tra kỹ để đảm bảo bạn đang xác minh các khoá đó theo đúng chứng chỉ khoá công khai.
Nếu không, nếu mọi thứ đều ổn, thì điều này có nghĩa là tính xác thực của chữ ký mã đã được xác minh cho tệp APK mà bạn đang xác thực.
Xác minh việc đưa gói vào (Bằng chứng về việc đưa vào)
Bằng cách sử dụng tải trọng mà bạn đã tạo trước đó, giờ đây, bạn đã sẵn sàng kiểm thử xem gói có liên quan có được đưa vào nhật ký minh bạch hay không.
Công cụ chứng minh việc đưa vào đã được phát hành trong kho lưu trữ avb
trong Dự án nguồn mở Android. Cách chạy:
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
Trình xác minh sử dụng điểm kiểm tra tương ứng và nội dung nhật ký (có trong thư mục thẻ thông tin) để kiểm tra xem tải trọng APK của bạn có trong nhật ký minh bạch hay không, xác minh rằng tải trọng đó thực sự do Google phát hành.
Kết quả của lệnh được ghi vào stdout:
OK. inclusion check success!
nếu mã của gói có trong nhật ký,FAILURE
nếu không.