Lược đồ chữ ký APK phiên bản 3

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
    • 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ên signed 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ên signed 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.

Quy trình xác minh chữ ký APK

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

  1. Tìm khối ký APK và xác minh rằng:
    1. Hai trường kích thước của khối ký APK chứa cùng một giá trị.
    2. Ngay sau thư mục trung tâm ZIP là bản ghi Kết thúc thư mục trung tâm ZIP.
    3. 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.
  2. 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.
  3. Đố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:
    1. Chọn signature algorithm ID được hỗ trợ mạnh nhất trong signatures. Thứ tự độ mạnh tuỳ thuộc vào từng phiên bản triển khai/nền tảng.
    2. Xác minh signature tương ứng từ signatures với signed data bằng public key. (Giờ đây, bạn có thể phân tích cú pháp signed data một cách an toàn.)
    3. 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.
    4. Xác minh rằng danh sách thứ tự mã nhận dạng thuật toán chữ ký trong digestssignatures giống hệt nhau. (Đây là cách để ngăn việc xoá/thêm chữ ký.)
    5. 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.
    6. 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.
    7. Xác minh rằng SubjectPublicKeyInfo của certificate đầu tiên của certificates giống với public key.
    8. 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.
  4. 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ới signer đó.

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/.