Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

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

Sơ đồ chữ ký APK v2 là một sơ đồ chữ ký toàn bộ tệp giúp tăng tốc độ xác minh và tăng cường đảm bảo tính toàn vẹn bằng cách phát hiện bất kỳ thay đổi nào đối với các phần được bảo vệ của APK.

Việc ký bằng APK Signature Scheme v2 sẽ chèn một APK Signing Block vào tệp APK ngay trước phần ZIP Central Directory. Bên trong Khối ký APK, chữ ký v2 và thông tin nhận dạng người ký được lưu trữ trong Khối ký kết APK v2 .

APK trước và sau khi ký

Hình 1. APK trước và sau khi ký

APK Signature Scheme v2 đã được giới thiệu trong Android 7.0 (Nougat). Để làm cho APK có thể cài đặt trên Android 6.0 (Marshmallow) và các thiết bị cũ hơn, APK đó phải được ký bằng cách ký JAR trước khi được ký bằng lược đồ v2.

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à mới hơn được lưu trữ bên trong Khối ký APK, một vùng chứa mới được giới thiệu để hỗ trợ Sơ đồ chữ ký APK v2. Trong tệp APK, Khối ký APK nằm ngay trước Thư mục trung tâm ZIP, nằm ở cuối tệp.

Khối chứa các cặp giá trị ID được bao bọc theo cách giúp định vị khối trong APK dễ dàng hơn. Chữ ký v2 của APK được lưu trữ dưới dạng cặp giá trị ID với ID 0x7109871a.

Định dạng

Định dạng của Khối ký APK như sau (tất cả các trường số đều là little-endian):

  • size of block bằng byte (không bao gồm trường này) (uint64)
  • Chuỗi các cặp giá trị ID có tiền tố uint64:
    • ID (uint32)
    • value (độ dài thay đổi: độ dài của cặp - 4 byte)
  • size of block bằng byte — giống như trường đầu tiên (uint64)
  • magic “APK Sig Block 42” (16 byte)

APK được phân tích cú pháp bằng cách tìm đầu tiên của Thư mục Trung tâm ZIP (bằng cách tìm bản ghi ZIP Cuối Thư mục Trung tâm ở cuối tệp, sau đó đọc phần bù bắt đầu của Thư mục Trung tâm từ bản ghi). Giá trị magic cung cấp một cách nhanh chóng để thiết lập rằng những gì đứng trước Thư mục trung tâm có khả năng là Khối ký APK. size of block sau đó trỏ đến đầu khối trong tệp một cách hiệu quả.

Các cặp giá trị ID có ID không xác định nên được bỏ qua khi diễn giải khối.

Lược đồ chữ ký APK v2 Block

APK được ký bởi một hoặc nhiều người ký / danh tính, mỗi người được đại diện bởi một khóa ký. Thông tin này được lưu trữ dưới dạng khối APK Signature Scheme v2. Đối với mỗi người ký, thông tin sau được lưu trữ:

  • (thuật toán chữ ký, thông báo, chữ ký) bộ giá trị. Thông báo được lưu trữ để tách xác minh chữ ký khỏi kiểm tra tính toàn vẹn của nội dung APK.
  • Chuỗi chứng chỉ X.509 đại diện cho danh tính của người ký.
  • Các thuộc tính bổ sung dưới dạng cặp khóa-giá trị.

Đối với mỗi người ký, APK được xác minh bằng chữ ký được hỗ trợ từ danh sách được cung cấp. Chữ ký với các thuật toán chữ ký không xác định bị bỏ qua. Tùy thuộc vào mỗi triển khai để chọn chữ ký nào sẽ sử dụng khi gặp nhiều chữ ký được hỗ trợ. Điều này cho phép giới thiệu các phương pháp ký mạnh hơn trong tương lai theo cách tương thích ngược. Cách tiếp cận được đề xuất là xác minh chữ ký mạnh nhất.

Định dạng

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

Định dạng của APK Signature Scheme v2 Block như sau (tất cả các giá trị số đều là little-endian, tất cả các trường có tiền tố độ dài sử dụng uint32 cho độ dài):

  • 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 các thông báo có tiền tố độ digests :
      • trình tự có tiền tố độ dài của chứng chỉ certificates :
        • chứng chỉ certificate có tiền tố độ dài (mẫu ASN.1 DER)
      • chuỗi các additional attributes có tiền tố chiều dài:
        • ID (uint32)
        • value (biến-độ dài: độ dài của thuộc tính bổ sung - 4 byte)
    • chuỗi signatures tiền tố độ dài có tiền tố độ dài:
      • signature algorithm ID (uint32)
      • signature tiền tố độ dài trên signed data
    • public key có tiền tố độ dài (SubjectPublicKeyInfo, biểu mẫu ASN.1 DER)

ID thuật toán chữ ký

  • 0x0101 — RSASSA-PSS với thông báo SHA2-256, SHA2-256 MGF1, 32 byte muối, trailer: 0xbc
  • 0x0102 — RSASSA-PSS với thông báo SHA2-512, SHA2-512 MGF1, 64 byte muối, đoạn giới thiệu: 0xbc
  • 0x0103 — RSASSA-PKCS1-v1_5 với thông báo SHA2-256. Điều này dành cho các hệ thống xây dựng yêu cầu chữ ký xác định.
  • 0x0104 — RSASSA-PKCS1-v1_5 với thông báo SHA2-512. Điều này dành cho các hệ thống xây dựng yêu cầu chữ ký xác định.
  • 0x0201 — ECDSA với thông báo SHA2-256
  • 0x0202 — ECDSA với thông báo SHA2-512
  • 0x0301 — DSA với thông báo SHA2-256

Tất cả các thuật toán chữ ký trên đều được hỗ trợ bởi nền tảng Android. Các công cụ ký có thể hỗ trợ một tập hợp con của các thuật toán.

Kích thước phím được hỗ trợ và đường cong EC:

  • RSA: 1024, 2048, 4096, 8192, 16384
  • EC: NIST P-256, P-384, P-521
  • DSA: 1024, 2048, 3072

Nội dung được bảo vệ toàn vẹn

Với mục đích bảo vệ nội dung APK, APK bao gồm bốn phần:

  1. Nội dung của các mục nhập ZIP (từ độ lệch 0 cho đến khi bắt đầu Khối ký APK)
  2. Khối ký APK
  3. Thư mục trung tâm ZIP
  4. ZIP Cuối Thư mục Trung tâm

Các phần APK sau khi ký

Hình 2. Các phần APK sau khi ký

Sơ đồ chữ ký APK v2 bảo vệ tính toàn vẹn của các phần 1, 3, 4 và các khối signed data của Sơ đồ chữ ký APK v2 Khối có bên trong phần 2.

Tính toàn vẹn của các phần 1, 3 và 4 được bảo vệ bởi một hoặc nhiều bản phân tích nội dung của chúng được lưu trữ trong các khối signed data , đến lượt nó, được bảo vệ bằng một hoặc nhiều chữ ký.

Thông báo trên các phần 1, 3 và 4 được tính như sau, tương tự như cây Merkle hai cấp. Mỗi phần được chia thành các phần 1 MB (2 20 byte) liên tiếp. Đoạn cuối cùng trong mỗi phần có thể ngắn hơn. Bản tóm tắt của mỗi đoạn được tính dựa trên việc ghép byte 0xa5 , độ dài của đoạn tính bằng byte (little-endian uint32) và nội dung của đoạn này. Thông báo cấp cao nhất được tính toán dựa trên việc ghép byte 0x5a , số lượng các phần (little-endian uint32) và nối các thông báo của các phần theo thứ tự các phần xuất hiện trong APK. Bản tổng hợp được tính toán theo kiểu phân khúc để cho phép tăng tốc độ tính toán bằng cách song song hóa nó.

Thông báo APK

Hình 3. Thông báo APK

Việc bảo vệ phần 4 (ZIP End of Central Directory) rất phức tạp bởi phần chứa phần bù của ZIP Central Directory. Ví dụ: bù đắp thay đổi khi kích thước của Khối ký APK thay đổi khi một chữ ký mới được thêm vào. Do đó, khi thông báo điện toán qua ZIP End of Central Directory, trường chứa phần bù của ZIP Central Directory phải được coi là chứa phần bù của Khối ký APK.

Bảo vệ khôi phục

Kẻ tấn công có thể cố gắng xác minh APK ký v2 là APK ký v1 trên nền tảng Android hỗ trợ xác minh APK ký v2. Để giảm thiểu cuộc tấn công này, các APK ký v2 cũng được ký v1 phải chứa thuộc tính X-Android-APK-Signed trong phần chính của tệp META-INF / *. SF của chúng. Giá trị của thuộc tính là một tập hợp các ID lược đồ chữ ký APK được phân tách bằng dấu phẩy (ID của lược đồ này là 2). Khi xác minh chữ ký v1, người xác minh APK được yêu cầu từ chối các APK không có chữ ký cho lược đồ chữ ký APK mà người xác minh thích từ tập hợp này (ví dụ: lược đồ v2). Sự bảo vệ này dựa trên thực tế là nội dung các tệp META-INF / *. SF được bảo vệ bằng chữ ký v1. Xem phần xác minh APK đã ký JAR .

Kẻ tấn công có thể cố gắng loại bỏ các chữ ký mạnh mẽ hơn từ Gói chữ ký APK v2 Block. Để giảm thiểu cuộc tấn công này, danh sách các ID thuật toán chữ ký mà APK đã được ký được lưu trữ trong khối signed data được bảo vệ bởi từng chữ ký.

xác minh

Trong Android 7.0 trở lên, APK có thể được xác minh theo Sơ đồ chữ ký APK v2 + hoặc ký JAR (sơ đồ v1). Các nền tảng cũ hơn bỏ qua chữ ký v2 và chỉ xác minh chữ ký v1.

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

Hình 4. Quy trình xác minh chữ ký APK (các bước mới màu đỏ)

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

  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. ZIP Central Directory ngay sau ZIP Bản ghi cuối của Central Directory.
    3. ZIP End of Central Directory không được theo sau bởi nhiều dữ liệu hơn.
  2. Xác định vị trí Khối chữ ký APK v2 đầu tiên bên trong Khối chữ ký APK. Nếu Khối v2 nếu có, 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 đồ v1 .
  3. Đối với mỗi signer trong Khối sơ đồ chữ ký APK v2:
    1. Chọn signature algorithm ID được hỗ trợ mạnh nhất từ ​​các signatures . Thứ tự sức mạnh 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ừ các signatures so với signed data bằng public key . (Bây giờ có thể an toàn để phân tích cú pháp signed data .)
    3. Xác minh rằng danh sách các ID thuật toán chữ ký đã được sắp xếp trong các thông digestssignatures là giống hệt nhau. (Điều này là để ngăn chặn việc xóa / thêm chữ ký.)
    4. Tính toán thông báo về nội dung APK bằng cách sử dụng thuật toán thông báo giống như thuật toán thông báo được sử dụng bởi thuật toán chữ ký.
    5. Xác minh rằng thông báo được tính toán giống với digest tương ứng từ các thông digests .
    6. Xác minh rằng SubjectPublicKeyInfo của chứng chỉ đầu tiên của certificate certificates giống với public key .
  4. Xác minh thành công nếu tìm thấy ít nhất một signer và bước 3 đã thành công cho mỗi signer được tìm thấy.

Lưu ý : Không được xác minh APK bằng lược đồ v1 nếu lỗi xảy ra ở bước 3 hoặc 4.

Xác minh APK do JAR ký (lược đồ v1)

APK được ký bằng JAR là JAR được ký chuẩn , phải chứa chính xác các mục nhập được liệt kê trong META-INF / MANIFEST.MF và trong đó tất cả các mục nhập phải được ký bởi cùng một nhóm người ký. Tính toàn vẹn của nó được xác minh như sau:

  1. Mỗi người ký được đại diện bởi một mục nhập JAR META-INF / <signer> .SF và META-INF / <signer>. (RSA | DSA | EC).
  2. <signer>. (RSA | DSA | EC) là một PKCS # 7 CMS ContentInfo với cấu trúc SignedData có chữ ký được xác minh qua tệp <signer> .SF.
  3. Tệp <signer> .SF chứa toàn bộ tệp thông báo về META-INF / MANIFEST.MF và thông báo của từng phần của META-INF / MANIFEST.MF. Thông báo toàn bộ tệp của MANIFEST.MF đã được xác minh. Nếu không thành công, thông báo của từng phần MANIFEST.MF sẽ được xác minh thay thế.
  4. META-INF / MANIFEST.MF chứa, đối với mỗi mục nhập JAR được bảo vệ toàn vẹn, một phần được đặt tên tương ứng chứa thông báo về nội dung không nén của mục nhập. Tất cả những tiêu chuẩn này đã được xác minh.
  5. Xác minh APK không thành công nếu APK chứa các mục nhập JAR không được liệt kê trong MANIFEST.MF và không phải là một phần của chữ ký JAR.

Do đó, chuỗi bảo vệ là <signer>. (RSA | DSA | EC) -> <signer> .SF -> MANIFEST.MF -> nội dung của mỗi mục nhập JAR được bảo vệ toàn vẹn.