Android 9 hỗ trợ tính năng xoay vòng khoá APK, cho phép các ứng dụng thay đổi khoá ký trong quá trình cập nhật APK. Để việc xoay vòng trở nên thực tế, tệp APK phải cho biết mức độ tin cậy giữa khoá ký mới và cũ. Để hỗ trợ tính năng xoay vòng khoá, chúng tôi đã cập nhật lược đồ chữ ký APK từ phiên bản 2 lên phiên bản 3 để cho phép sử dụng khoá mới và khoá cũ. Phiên bản 3 thêm thông tin về các phiên bản SDK được hỗ trợ và cấu trúc bằng chứng xoay vòng vào khối ký APK.
Khối ký APK
Để duy trì khả năng tương thích ngược với định dạng APK v1, chữ ký APK v2 và v3 được lưu trữ bên trong một khối ký APK, nằm ngay trước Thư mục trung tâm ZIP.
Định dạng khối ký APK phiên bản 3 giống với phiên bản 2. Chữ ký v3 của APK được lưu trữ dưới dạng một cặp giá trị-mã nhận dạng có mã nhận dạng là 0xf05368c0.
Khối lược đồ chữ ký APK phiên bản 3
Lược đồ v3 được thiết kế rất giống với lược đồ v2. Định dạng chung của tệp này cũng giống như tệp ECDSA và hỗ trợ cùng một mã nhận dạng thuật toán chữ ký, kích thước khoá và đường cong EC.
Tuy nhiên, lược đồ v3 thêm thông tin về các phiên bản SDK được hỗ trợ và cấu trúc bằng chứng xoay.
Định dạng
Khối lược đồ chữ ký APK phiên bản 3 được lưu trữ bên trong khối ký APK theo mã nhận dạng 0xf05368c0
.
Định dạng của khối lược đồ chữ ký APK phiên bản 3 tuân theo định dạng của phiên bản 2:
- trình tự có tiền tố độ dài của
signer
có tiền tố độ dài:signed data
có tiền tố độ dài:- trình tự có tiền tố độ dài của
digests
có tiền tố độ dài:signature algorithm ID
(4 byte)digest
(có tiền tố độ dài)
- Trình tự có tiền tố độ dài của X.509
certificates
:certificate
X.509 có tiền tố độ dài (dạng ASN.1 DER)
minSDK
(uint32) – bạn nên bỏ qua chữ ký này nếu phiên bản nền tảng thấp hơn số này.maxSDK
(uint32) – bạn nên bỏ qua chữ ký này nếu phiên bản nền tảng cao hơn số này.- trình tự có tiền tố độ dài của
additional attributes
có tiền tố độ dài:ID
(uint32)value
(độ dài biến đổi: độ dài của thuộc tính bổ sung – 4 byte)ID - 0x3ba06f8c
value -
Cấu trúc proof-of-rotation
- trình tự có tiền tố độ dài của
minSDK
(uint32) – bản sao của giá trị minSDK trong phần dữ liệu đã ký – dùng để bỏ qua việc xác minh chữ ký này nếu nền tảng hiện tại không nằm trong phạm vi. Phải khớp với giá trị dữ liệu đã ký.maxSDK
(uint32) – bản sao của giá trị maxSDK trong phần dữ liệu đã ký – dùng để bỏ qua việc xác minh chữ ký này nếu nền tảng hiện tại không nằm trong phạm vi. Phải khớp với giá trị dữ liệu đã ký.- trình tự có tiền tố độ dài của
signatures
có tiền tố độ dài:signature algorithm ID
(uint32)signature
có tiền tố độ dài trênsigned data
public key
có tiền tố độ dài (SubjectPublicKeyInfo, ASN.1 DER)
Cấu trúc proof-of-rotation và self-trusted-old-certs
Cấu trúc bằng chứng xoay vòng cho phép các ứng dụng xoay vòng chứng chỉ ký mà không bị chặn trên các ứng dụng khác mà chúng giao tiếp. Để thực hiện việc này, chữ ký ứng dụng chứa hai phần dữ liệu mới:
- xác nhận cho bên thứ ba rằng chứng chỉ ký của ứng dụng có thể được tin cậy bất cứ khi nào các chứng chỉ trước đó được tin cậy
- các chứng chỉ ký cũ của ứng dụng mà chính ứng dụng vẫn tin tưởng
Thuộc tính bằng chứng về việc xoay vòng trong phần dữ liệu đã ký bao gồm một danh sách liên kết đơn, trong đó mỗi nút chứa một chứng chỉ ký dùng để ký các phiên bản trước của ứng dụng. Thuộc tính này dùng để chứa cấu trúc dữ liệu bằng chứng về việc xoay vòng và chứng chỉ cũ tự tin cậy. Danh sách được sắp xếp theo phiên bản, trong đó chứng chỉ ký cũ nhất tương ứng với nút gốc. Cấu trúc dữ liệu bằng chứng về việc xoay vòng được tạo bằng cách yêu cầu chứng chỉ trong mỗi nút ký chứng chỉ tiếp theo trong danh sách, nhờ đó truyền cho mỗi khoá mới bằng chứng rằng khoá đó đáng tin cậy như(các) khoá cũ.
Cấu trúc dữ liệu self-trusted-old-certs được tạo bằng cách thêm cờ vào mỗi nút cho biết thuộc tính và thành viên của nút đó trong tập hợp. Ví dụ: có thể có một cờ cho biết chứng chỉ ký tại một nút nhất định là đáng tin cậy để nhận quyền ký trên Android. Cờ này cho phép các ứng dụng khác được ký bằng chứng chỉ cũ vẫn được cấp quyền chữ ký do một ứng dụng được ký bằng chứng chỉ ký mới xác định. Vì toàn bộ thuộc tính bằng chứng xoay nằm trong phần dữ liệu đã ký của trường signer
v3, nên thuộc tính này được bảo vệ bằng khoá dùng để ký tệp APK chứa thuộc tính đó.
Định dạng này loại trừ nhiều khoá ký và sự hội tụ của nhiều chứng chỉ ký cấp trên thành một (nhiều nút bắt đầu đến một bồn lưu trữ chung).
Định dạng
Bằng chứng về việc xoay được lưu trữ bên trong khối lược đồ chữ ký APK phiên bản 3 theo mã nhận dạng 0x3ba06f8c
. Định dạng của tệp này là:
- trình tự có tiền tố độ dài của
levels
có tiền tố độ dài:signed data
có tiền tố độ dài (theo chứng chỉ trước đó – nếu có)certificate
X.509 có tiền tố độ dài (dạng ASN.1 DER)signature algorithm ID
(uint32) – thuật toán mà chứng chỉ sử dụng ở cấp trước
flags
(uint32) – cờ cho biết liệu chứng chỉ này có nằm trong cấu trúc self-trusted-old-certs hay không và cho những thao tác nào.signature algorithm ID
(uint32) – phải khớp với giá trị trong phần dữ liệu đã ký ở cấp tiếp theo.signature
có tiền tố độ dài trênsigned data
ở trên
Nhiều chứng chỉ
Không hỗ trợ nhiều chữ ký và Google Play không phát hành những ứng dụng được ký bằng nhiều chứng chỉ.
Xác minh
Trong Android 9 trở lên, bạn có thể xác minh tệp APK theo Lược đồ chữ ký APK phiên bản 3, phiên bản 2 hoặc phiên bản 1. Các nền tảng cũ bỏ qua chữ ký v3 và cố gắng xác minh chữ ký v2, sau đó là v1.
Hình 1. Quy trình xác minh chữ ký APK
Xác minh lược đồ chữ ký APK phiên bản 3
- Tìm khối ký APK và xác minh rằng:
- Hai trường kích thước của khối ký APK chứa cùng một giá trị.
- Ngay sau thư mục trung tâm ZIP là bản ghi Kết thúc thư mục trung tâm ZIP.
- Không có dữ liệu nào theo sau phần Kết thúc thư mục trung tâm của tệp ZIP.
- Tìm khối lược đồ chữ ký APK phiên bản 3 đầu tiên bên trong khối ký APK. Nếu có khối v3, hãy chuyển sang bước 3. Nếu không, hãy quay lại xác minh tệp APK bằng lược đồ v2.
- Đối với mỗi
signer
trong khối lược đồ chữ ký APK phiên bản 3 có phiên bản SDK tối thiểu và tối đa nằm trong phạm vi của nền tảng hiện tại:- Chọn
signature algorithm ID
được hỗ trợ mạnh nhất trongsignatures
. Thứ tự độ mạnh tuỳ thuộc vào từng phiên bản triển khai/nền tảng. - Xác minh
signature
tương ứng từsignatures
vớisigned data
bằngpublic key
. (Giờ đây, bạn có thể phân tích cú phápsigned data
một cách an toàn.) - Xác minh rằng phiên bản SDK tối thiểu và tối đa trong dữ liệu đã ký khớp với các phiên bản được chỉ định cho
signer
. - Xác minh rằng danh sách thứ tự mã nhận dạng thuật toán chữ ký trong
digests
vàsignatures
giống hệt nhau. (Đây là cách để ngăn việc xoá/thêm chữ ký.) - Tính toán hàm băm của nội dung APK bằng cách sử dụng cùng một thuật toán băm với thuật toán băm mà thuật toán chữ ký sử dụng.
- Xác minh rằng chuỗi đại diện được tính toán giống với
digest
tương ứng từdigests
. - Xác minh rằng SubjectPublicKeyInfo của
certificate
đầu tiên củacertificates
giống vớipublic key
. - Nếu thuộc tính bằng chứng xoay có trong
signer
, hãy xác minh rằng cấu trúc này hợp lệ vàsigner
này là chứng chỉ cuối cùng trong danh sách.
- Chọn
- Quá trình xác minh sẽ thành công nếu tìm thấy đúng một
signer
trong phạm vi của nền tảng hiện tại và bước 3 thành công đối vớisigner
đó.
Xác nhận kết quả
Để kiểm tra xem thiết bị của bạn có hỗ trợ đúng cách phiên bản 3 hay không, hãy chạy các kiểm thử CTS PkgInstallSignatureVerificationTest.java
trong cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.