Lược đồ chữ ký APK v3

Android 9 hỗ trợ xoay vòng khóa APK , giúp ứng dụng có khả năng thay đổi khóa ký như một phần của bản cập nhật APK. Để việc xoay vòng trở nên thực tế, APK phải cho biết mức độ tin cậy giữa khóa ký mới và khóa ký cũ. Để hỗ trợ xoay vòng khóa, chúng tôi đã cập nhật sơ đồ chữ ký APK từ v2 lên v3 để cho phép sử dụng khóa mới và khóa cũ. V3 bổ sung thông tin về các phiên bản SDK được hỗ trợ và cấu trúc proof-of-rotation 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 Khối ký APK, nằm ngay trước Thư mục trung tâm ZIP.

Định dạng Khối ký APK v3 giống như v2 . Chữ ký v3 của APK được lưu trữ dưới dạng cặp giá trị ID có ID 0xf05368c0.

Khối chữ ký APK v3

Sơ đồ v3 được thiết kế rất giống với sơ đồ v2 . Nó có cùng định dạng chung và hỗ trợ cùng ID thuật toán chữ ký , kích thước khóa và đường cong EC.

Tuy nhiên, lược đồ v3 bổ sung thêm thông tin về các phiên bản SDK được hỗ trợ và cấu trúc proof-of-rotation.

Định dạng

Khối chữ ký APK v3 được lưu trữ bên trong Khối ký APK dưới ID 0xf05368c0 .

Định dạng của Khối sơ đồ chữ ký APK v3 tuân theo định dạng của v2:

  • chuỗi có tiền tố độ dài của signer có tiền tố độ dài:
    • signed data có tiền tố dài:
      • chuỗi 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)
      • chuỗi tiền tố có độ dài của certificates X.509:
        • certificate chỉ X.509 có tiền tố dài (mẫu ASN.1 DER)
      • minSDK (uint32) - người ký này sẽ bị bỏ qua nếu phiên bản nền tảng thấp hơn con số này.
      • maxSDK (uint32) - người ký này sẽ bị bỏ qua nếu phiên bản nền tảng cao hơn con số này.
      • chuỗi có tiền tố độ dài của additional attributes độ dài:
        • ID (uint32)
        • value (độ dài thay đổi: độ dài của thuộc tính bổ sung - 4 byte)
        • ID - 0x3ba06f8c
        • value - Cấu trúc bằng chứng xoay
    • minSDK (uint32) - bản sao của giá trị minSDK trong phần dữ liệu đã ký - được sử dụng để bỏ qua 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ý - được sử dụng để bỏ qua 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ý.
    • chuỗi 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 độ dài (SubjectPublicKeyInfo, mẫu ASN.1 DER)

Cấu trúc proof-of-rotation và self-trust-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 liên lạc. Để thực hiện điều này, chữ ký ứng dụng chứa hai phần dữ liệu mới:

  • xác nhận cho các bên thứ ba rằng chứng chỉ ký của ứng dụng có thể được tin cậy ở bất kỳ nơi nào mà chứng chỉ tiền nhiệm của nó được tin cậy
  • Chứng chỉ ký cũ hơn của ứng dụng mà bản thân ứng dụng vẫn tin tưởng

Thuộc tính proof-of-rotation trong phần dữ liệu đã ký bao gồm một danh sách liên kết đơn, với mỗi nút chứa chứng chỉ ký được sử dụng để ký các phiên bản trước của ứng dụng. Thuộc tính này có nghĩa là chứa các cấu trúc dữ liệu bằng chứng 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 có 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 xoay vòng được xây dựng bằng cách yêu cầu chứng chỉ trong mỗi nút ký vào nút tiếp theo trong danh sách và do đó đưa vào mỗi khóa mới bằng chứng cho thấy nó đáng tin cậy như (các) khóa cũ hơn.

Cấu trúc dữ liệu self-trust-old-certs được xây dựng bằng cách thêm cờ vào mỗi nút cho biết thành viên và thuộc tính của nó trong tập hợp. Ví dụ: có thể xuất hiện một cờ cho biết rằng chứng chỉ ký tại một nút nhất định là đáng tin cậy để lấy quyền chữ ký của Android. Cờ này cho phép các ứng dụng khác được ký bằng chứng chỉ cũ hơn vẫn được cấp quyền chữ ký được xác định bởi ứng dụng được ký bằng chứng chỉ ký mới. Bởi vì toàn bộ thuộc tính proof-of-rotation nằm trong phần dữ liệu đã ký của trường signer v3 nên nó được bảo vệ bằng khóa được sử dụng để ký gói ứng dụng chứa.

Định dạng này ngăn cản nhiều khóa ký và sự hội tụ của các chứng chỉ ký tổ tiên khác nhau thành một (nhiều nút khởi đầu cho một điểm chung).

Định dạng

Bằng chứng xoay vòng được lưu trữ bên trong Khối Lược đồ Chữ ký APK v3 dưới ID 0x3ba06f8c . Định dạng của nó là:

  • chuỗi 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 tồn tại)
      • certificate chỉ X.509 có tiền tố dài (mẫu ASN.1 DER)
      • signature algorithm ID (uint32) - thuật toán được chứng chỉ ở cấp độ trước sử dụng
    • flags (uint32) - cờ cho biết chứng chỉ này có nằm trong cấu trúc self-trust-old-certs hay không và cho những hoạt động nào.
    • signature algorithm ID (uint32) - phải khớp với ID thuật toán từ 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ỉ

Android hiện coi APK được ký bằng nhiều chứng chỉ là có mã nhận dạng ký duy nhất tách biệt với các chứng chỉ bao gồm. Do đó, thuộc tính proof-of-rotation trong phần dữ liệu đã ký tạo thành một biểu đồ tuần hoàn có hướng, tốt hơn có thể được xem dưới dạng danh sách liên kết đơn, với mỗi bộ người ký cho một phiên bản nhất định đại diện cho một nút. Điều này làm tăng thêm độ phức tạp cho cấu trúc bằng chứng xoay vòng (phiên bản nhiều người ký bên dưới). Đặc biệt, việc đặt hàng trở thành một mối quan tâm. Hơn nữa, không thể ký các APK một cách độc lập nữa vì cấu trúc bằng chứng luân chuyển phải có các chứng chỉ ký cũ ký vào bộ chứng chỉ mới, thay vì ký từng cái một. Ví dụ: APK được ký bởi khóa A muốn được ký bởi hai khóa mới B và C không thể có người ký B chỉ bao gồm chữ ký của A hoặc B, vì đó là danh tính ký khác với B và C. Điều này sẽ có nghĩa là người ký phải phối hợp trước khi xây dựng cấu trúc đó.

Thuộc tính bằng chứng luân chuyển nhiều người ký

  • chuỗi có tiền tố độ dài của sets có tiền tố độ dài:
    • signed data (theo tập trước - nếu tồn tại)
      • chuỗi certificates có tiền tố dài
        • certificate chỉ X.509 có tiền tố dài (mẫu ASN.1 DER)
      • Chuỗi signature algorithm IDs (uint32) - một ID cho mỗi chứng chỉ từ bộ trước, theo cùng một thứ tự.
    • flags (uint32) - cờ cho biết liệu bộ chứng chỉ này có nằm trong cấu trúc self-trust-old-certs hay không và cho những hoạt động nào.
    • chuỗi có tiền tố độ dài của signatures có tiền tố độ dài:
      • signature algorithm ID (uint32) - phải khớp với ID từ phần dữ liệu đã ký
      • signature có tiền tố dài trên signed data ở trên

Nhiều tổ tiên trong cấu trúc proof-of-rotation

Lược đồ v3 cũng không xử lý hai khóa khác nhau xoay sang cùng một khóa ký cho cùng một ứng dụng. Điều này khác với trường hợp mua lại, trong đó công ty mua lại muốn chuyển ứng dụng được mua lại để sử dụng khóa ký của nó để chia sẻ quyền. Việc mua lại được xem là trường hợp sử dụng được hỗ trợ vì ứng dụng mới sẽ được phân biệt bằng tên gói và có thể chứa cấu trúc proof-of-rotation của riêng nó. Trường hợp không được hỗ trợ, cùng một ứng dụng có hai đường dẫn khác nhau để đạt được cùng một chứng chỉ, đã phá vỡ nhiều giả định được đưa ra trong thiết kế xoay vòng khóa.

xác minh

Trong Android 9 trở lên, APK có thể được xác minh theo Lược đồ chữ ký APK v3, lược đồ v2 hoặc lược đồ v1. Các nền tảng cũ hơn bỏ qua chữ ký v3 và cố gắng xác minh chữ ký v2, sau đó là v1.

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

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

Xác minh sơ đồ chữ ký APK v3

  1. Xác định vị trí 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 Cuối thư mục Trung tâm ZIP.
    3. ZIP Cuối thư mục trung tâm không được theo sau bởi nhiều dữ liệu hơn.
  2. Xác định vị trí Khối sơ đồ chữ ký APK v3 đầu tiên bên trong Khối ký APK. Nếu Khối v3 xuất hiện, hãy chuyển sang bước 3. Nếu không, hãy quay lại xác minh APK bằng lược đồ v2 .
  3. Đối với mỗi signer trong Khối Lược đồ chữ ký APK v3 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 từ signatures . Thứ tự cường độ tùy 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 đối với signed data bằng public key . (Bây giờ việc phân tích signed data là an toàn.)
    3. Xác minh phiên bản SDK tối thiểu và tối đa trong dữ liệu đã ký khớp với phiên bản được chỉ định cho signer .
    4. Xác minh rằng danh sách thứ tự các ID thuật toán chữ ký trong digestssignatures là giống hệt nhau. (Điều này nhằm ngăn chặn việc tước/bổ sung chữ ký.)
    5. Tính toán thông báo tóm tắt nội dung APK bằng cách sử dụng thuật toán tóm tắt giống như thuật toán tóm tắt được thuật toán chữ ký sử dụng.
    6. Xác minh rằng thông báo được tính toán giống hệt với digest tương ứng từ digests .
    7. Xác minh rằng Chủ đềPublicKeyInfo của certificate certificates đầu tiên giống hệt với public key .
    8. Nếu thuộc tính proof-of-rotation tồn tại đối với signer , hãy xác minh rằng cấu trúc đó hợp lệ và signer này là chứng chỉ cuối cùng trong danh sách.
  4. Việc xác minh thành công nếu tìm thấy chính xác 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 đó.

Thẩm định

Để kiểm tra xem thiết bị của bạn có hỗ trợ v3 đúng cách hay không, hãy chạy kiểm tra PkgInstallSignatureVerificationTest.java CTS trong cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ .