Code Signing — ký mã là gì và cách hoạt động

Tác giả: IT Sectr Đã đăng: 2026-04-16 Thời gian đọc: 9 phút

Code Signing (ký mã) là cơ chế ký số cho các tệp thực thi, đảm bảo tính xác thực của nhà phát triển và tính toàn vẹn của ứng dụng. Trong Android, mọi tệp APK phải được ký bằng chứng chỉ trước khi cài đặt trên thiết bị hoặc xuất bản lên Google Play. Theo Google, 2024, Android hỗ trợ bốn thế hệ lược đồ ký: từ v1 dựa trên JAR đến v4 cho cài đặt phát trực tuyến.

Những điểm chính

  • Code Signing — chữ ký số của mã, xác nhận quyền tác giả và tính toàn vẹn của ứng dụng.
  • Trong Android, việc ký được thực hiện qua keystore — kho lưu trữ khóa và chứng chỉ.
  • Lược đồ v2 (APK Signature Scheme) là tiêu chuẩn chính từ Android 7.0, bảo vệ tất cả các byte của APK.
  • Luân chuyển khóa (v3, Android 9.0+) cho phép thay đổi khóa ký mà không xóa ứng dụng.
  • Google Play sử dụng Play App Signing để quản lý khóa tập trung.

Code Signing là gì?

Code Signing là một quy trình mật mã trong đó nhà phát triển ký mã thực thi bằng chứng chỉ số của họ. Chữ ký được tạo bằng mã hóa bất đối xứng: khóa riêng của nhà phát triển tạo chữ ký số và khóa công khai được nhúng vào chứng chỉ. Bất kỳ ai cũng có thể xác minh chữ ký bằng khóa công khai, nhưng không thể sửa đổi mã mà không phá vỡ chữ ký.

Trong phát triển di động, ký mã thực hiện ba chức năng. Thứ nhất — xác thực: người dùng và nền tảng có thể xác định nhà phát triển ứng dụng. Thứ hai — tính toàn vẹn: bất kỳ thay đổi nào đối với APK sau khi ký đều làm mất hiệu lực chữ ký. Thứ ba — cập nhật đáng tin cậy: nền tảng chỉ cho phép cập nhật ứng dụng bằng các APK được ký bằng cùng chứng chỉ với phiên bản đã cài đặt.

Tình trạng pháp lý

Chữ ký số của ứng dụng Android có ý nghĩa pháp lý. Theo luật pháp Nga (63-FZ) và eIDAS châu Âu, chữ ký điện tử đủ điều kiện tương đương với chữ ký viết tay. Tuy nhiên, ký APK bằng chứng chỉ tự ký (thông lệ phổ biến trong Android) không đủ điều kiện — nó xác nhận tính toàn vẹn, nhưng không xác nhận danh tính của nhà phát triển theo quan điểm pháp lý.

Lược đồ ký Android: v1, v2, v3, v4

Android hỗ trợ bốn lược đồ ký APK, mỗi lược đồ giải quyết các vấn đề của phiên bản trước và thêm các khả năng mới. Tất cả các lược đồ có thể cùng tồn tại trong một APK — điều này cần thiết cho khả năng tương thích ngược với các phiên bản Android cũ.

Lược đồ v1 (JAR signing) xuất hiện trong Android 1.0. Nó ký các tệp riêng lẻ bên trong kho lưu trữ APK bằng các mục nhập trong META-INF/MANIFEST.MF. Nhược điểm: kẻ tấn công có thể sửa đổi APK (thêm hoặc xóa tệp) và chỉ ký lại các tệp đã sửa đổi mà không ảnh hưởng đến phần còn lại. Điều này làm cho v1 dễ bị tổn thương trước một số cuộc tấn công. Lược đồ v2 (APK Signature Scheme), được giới thiệu trong Android 7.0, ký toàn bộ tệp APK như một tổng thể, bao gồm tất cả các byte ngoại trừ chữ ký, loại bỏ khả năng sửa đổi có chọn lọc.

Lược đồAndroidĐặc điểmLuân chuyển khóa
v1 (JAR)1.0+Ký từng tệpKhông
v27.0+Ký toàn bộ APKKhông
v39.0+Ký + luân chuyển
v411.0+Phát trực tuyến + ADB

v3: luân chuyển khóa ký

Lược đồ v3, được giới thiệu trong Android 9.0, giải quyết một vấn đề lâu dài: phải làm gì nếu khóa ký bị xâm phạm hoặc hết hạn? Trước đây, việc thay đổi khóa ký đồng nghĩa với việc ứng dụng bị coi là mới — không thể cài đặt nó lên trên ứng dụng hiện có. v3 thêm cơ chế luân chuyển: APK có thể bao gồm bằng chứng luân chuyển (proof-of-rotation), được ký bằng khóa cũ. Hệ thống xác minh chuỗi và cho phép cập nhật ứng dụng được ký bằng khóa mới.

Keystore và chứng chỉ

Keystore là một vùng chứa an toàn chứa các khóa riêng và chứng chỉ để ký ứng dụng. Trong phát triển Android, định dạng JKS (Java KeyStore) hoặc PKCS12 được sử dụng. Keystore được tạo bằng tiện ích keytool, là một phần của JDK. Mỗi khóa trong kho được xác định bằng bí danh (alias) và được bảo vệ bằng mật khẩu.

Chứng chỉ trong keystore chứa khóa công khai và thông tin chủ sở hữu: tên tổ chức, quốc gia, thời hạn hiệu lực. Đối với ứng dụng Android, chứng chỉ có thể tự ký — Google không yêu cầu cơ quan cấp chứng chỉ (CA), điều này phân biệt Android với iOS. Tuy nhiên, thời hạn hiệu lực của chứng chỉ phải ít nhất 25 năm, vì ứng dụng sẽ được cập nhật bằng cùng một khóa.

bash
# Tạo keystore mới để ký
keytool -genkey -v -keystore my-release.keystore \
        -alias my-app-alias \
        -keyalg RSA \
        -keysize 2048 \
        -validity 10000

# Xem nội dung keystore
keytool -list -v -keystore my-release.keystore

Định dạng khóa

Android hỗ trợ hai thuật toán cho khóa ký: RSAECDSA. RSA với kích thước khóa 2048 bit là tiêu chuẩn thực tế, được hỗ trợ bởi tất cả các phiên bản Android. ECDSA (Thuật toán chữ ký số đường cong elliptic) với đường cong P-256 cung cấp cùng độ mạnh mật mã với kích thước khóa nhỏ hơn. Từ Android 9.0, ECDSA được khuyến nghị vì nó nhanh hơn trong xác minh trên thiết bị di động.

Cấu hình ký trong bản dựng

Trong Android Gradle Plugin, việc ký được cấu hình thông qua khối signingConfigs trong build.gradle cấp mô-đun. Đối với bản dựng gỡ lỗi, Android Studio tự động tạo keystore gỡ lỗi với mật khẩu đã biết. Đối với bản dựng phát hành, nhà phát triển chỉ định đường dẫn đến keystore, bí danh khóa và mật khẩu. Nên lưu trữ mật khẩu trong các tệp cấu hình riêng biệt, loại trừ khỏi kiểm soát phiên bản.

Thực hành hiện đại là quản lý ký tập trung thông qua CI/CD. Jenkins, GitLab CI hoặc GitHub Actions có thể lưu trữ keystore như một tạo phẩm được bảo vệ và mật khẩu như bí mật môi trường. Điều này ngăn chặn rò rỉ khóa qua kho lưu trữ và đơn giản hóa việc luân chuyển khóa khi cần thiết.

groovy
// build.gradle (cấp ứng dụng) — cấu hình ký
android {
    signingConfigs {
        release {
            storeFile file("my-release.keystore")
            storePassword System.getenv("KEYSTORE_PASSWORD")
            keyAlias System.getenv("KEY_ALIAS")
            keyPassword System.getenv("KEY_PASSWORD")
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

Ký nhiều lược đồ

Để tương thích tối đa, APK nên được ký bằng cả ba lược đồ (v1 + v2 + v3). Android Gradle Plugin bao gồm tất cả các lược đồ theo mặc định. APK chỉ được ký bằng v2 sẽ không cài đặt được trên Android 6.0 trở xuống. APK chỉ có v1 sẽ không nhận được lợi ích toàn vẹn của v2 trên Android 7.0+. Việc bao gồm tất cả các lược đồ không làm tăng kích thước APK quá 1–2% và đảm bảo tương thích với mọi thiết bị.

Play App Signing và quản lý khóa

Play App Signing là dịch vụ Google Play quản lý tập trung các khóa ký ứng dụng. Nhà phát triển tải lên APK được ký bằng khóa tải lên (upload key) lên Google Play Console và Google Play ký lại bằng khóa phân phối (distribution key) trước khi gửi đến người dùng. Điều này bảo vệ khóa phân phối khỏi mất mát hoặc xâm phạm.

Lợi ích của Play App Signing: bảo mật — khóa phân phối được lưu trữ trong kho lưu trữ an toàn của Google; luân chuyển — có thể yêu cầu thay đổi khóa qua bảng điều khiển; khôi phục — nếu mất khóa tải lên, có thể tạo khóa mới. Nhược điểm: đối với các ứng dụng tồn tại trước khi Play App Signing được giới thiệu, việc di chuyển yêu cầu tạo ứng dụng mới, vì khóa phân phối cũ đã được sử dụng.

bash
# Lấy dấu vân tay chứng chỉ (SHA-256)
keytool -list -v -keystore my-release.keystore \
        -alias my-app-alias | grep "SHA256"

# Xác minh chữ ký APK bằng apksigner
apksigner verify --verbose app-release.apk

Khôi phục khóa

Nếu mất khóa ký và không sử dụng Play App Signing, việc khôi phục khả năng cập nhật ứng dụng là không thể — sẽ phải tạo ứng dụng mới với tên gói mới. Đây là một trong những lý do chính để sử dụng Play App Signing. Google khuyến nghị giữ bản sao lưu keystore trong kho lưu trữ ngoại tuyến an toàn (ổ USB được mã hóa, két an toàn ngân hàng).

Xác minh chữ ký trên thiết bị

Khi cài đặt APK, Android thực hiện xác minh chữ ký qua nhiều giai đoạn. Thứ nhất — kiểm tra chứng chỉ: xem hết hạn chưa, định dạng có đúng không. Thứ hai — xác minh chữ ký: chữ ký mật mã có khớp với nội dung APK không. Thứ ba — so sánh chứng chỉ với phiên bản đã cài đặt: nếu ứng dụng đã tồn tại trên thiết bị, chứng chỉ phải khớp, nếu không việc cài đặt sẽ bị chặn.

Hệ thống xác minh được tích hợp trong PackageManagerService. Khi xử lý yêu cầu cài đặt, PMS trích xuất chữ ký từ APK, xác minh nó bằng lớp android.util.PackageParser và so sánh với chữ ký đã lưu của ứng dụng đã cài đặt (nếu có). Nếu không khớp, người dùng nhận được lỗi “INSTALL_FAILED_UPDATE_INCOMPATIBLE”. Cơ chế này ngăn chặn các cuộc tấn công thay thế (phần mềm độc hại không thể thay thế ứng dụng hợp pháp bằng phiên bản của chúng).

Xác minh bởi nhà phát triển

Nhà phát triển có thể độc lập xác minh chữ ký APK bằng tiện ích apksigner từ Android SDK Build Tools. Lệnh apksigner verify --verbose app.apk hiển thị APK được ký bằng lược đồ nào, chứng chỉ có hợp lệ không và chữ ký có khớp với nội dung không. Để xác minh theo chương trình chữ ký của ứng dụng đã cài đặt, sử dụng PackageManager.getPackageInfo() với cờ GET_SIGNATURES.

kotlin
// Xác minh chữ ký theo chương trình của ứng dụng đã cài đặt
fun getAppSignature(context: Context, packageName: String): String? {
    val pm = context.packageManager
    val info = pm.getPackageInfo(
        packageName,
        PackageManager.GET_SIGNATURES
    )
    return info.signatures?.firstOrNull()?.toCharsString()
}

Thực hành tốt nhất về bảo mật ký

Bảo mật khóa ký là một khía cạnh quan trọng của phát triển Android. Khóa bị xâm phạm cho phép kẻ tấn công ký các bản cập nhật ứng dụng của bạn bằng mã của chúng. Các quy tắc chính: không bao giờ lưu trữ khóa trong kho lưu trữ, không sử dụng một khóa cho các ứng dụng khác nhau, không truyền khóa qua các kênh không an toàn (email, tin nhắn).

Thực hành được khuyến nghị là phân tách khóa. Sử dụng khóa riêng cho mỗi ứng dụng và khóa riêng để tải lên Google Play (upload key). Đối với bản dựng gỡ lỗi, Android Studio tạo debug.keystore dùng chung — không được sử dụng nó cho bản dựng phát hành. Thời hạn hiệu lực của chứng chỉ nên là 25–30 năm (tiêu chuẩn hiện tại, được Google xác nhận).

Thực hànhKhuyến nghị
Lưu trữ khóaPhương tiện mã hóa, bí mật CI/CD
Thời hạn chứng chỉÍt nhất 25 năm
Thuật toánRSA 2048+ hoặc ECDSA P-256
Phân táchKhóa riêng cho mỗi ứng dụng
Sao lưuBản sao ngoại tuyến của keystore

Kiểm toán chữ ký

Thường xuyên kiểm tra tính toàn vẹn của chuỗi ký. Khi nhân viên có quyền truy cập khóa rời đi, hãy cập nhật khóa tải lên qua Google Play Console. Sử dụng các công cụ như Google Play Integrity API để xác minh rằng ứng dụng của bạn không bị giả mạo trên thiết bị của người dùng. API trả về dữ liệu về chữ ký và tính toàn vẹn, gửi chúng đến máy chủ để xác minh.

Câu hỏi thường gặp

Code Signing trong Android là gì?

Code Signing là chữ ký số của tệp APK xác nhận rằng ứng dụng được tạo bởi một nhà phát triển cụ thể và không bị sửa đổi sau khi ký. Nếu không có chữ ký, APK sẽ không cài đặt được trên thiết bị.

Làm thế nào để tạo khóa ký ứng dụng Android?

Sử dụng tiện ích keytool từ JDK: keytool -genkey -v -keystore my-release.keystore -alias my-alias -keyalg RSA -keysize 2048 -validity 10000. Chỉ định keystore kết quả trong build.gradle trong khối signingConfigs.

Điều gì xảy ra nếu tôi mất khóa ký?

Nếu mất khóa và bạn không sử dụng Play App Signing, việc cập nhật ứng dụng trở nên bất khả thi. Bạn sẽ phải tạo ứng dụng mới trên Google Play với tên gói mới. Sử dụng Play App Signing để bảo vệ khỏi mất khóa.

Sự khác biệt giữa lược đồ ký v1 và v2 là gì?

v1 ký từng tệp trong APK riêng lẻ — kẻ tấn công có thể sửa đổi một tệp và chỉ ký lại tệp đó. v2 ký toàn bộ APK như một tổng thể — bất kỳ thay đổi nào cũng làm mất hiệu lực chữ ký, cung cấp mức bảo mật cao hơn.

Play App Signing là gì?

Play App Signing là dịch vụ Google Play lưu trữ tập trung khóa phân phối ứng dụng. Nhà phát triển tải lên APK được ký bằng khóa tải lên và Google ký lại trước khi gửi đến người dùng, bảo vệ khóa khỏi mất mát hoặc đánh cắp.

Tổng kết

  • Code Signing là chữ ký số bắt buộc cho APK, đảm bảo tính xác thực và toàn vẹn của ứng dụng.
  • Android hỗ trợ bốn lược đồ ký: v1 (JAR), v2 (APK Signature), v3 (luân chuyển khóa) và v4 (phát trực tuyến).
  • Keystore là vùng chứa khóa an toàn được tạo qua keytool với thuật toán RSA 2048+.
  • Luân chuyển khóa (v3, Android 9.0+) cho phép thay đổi khóa ký mà không xóa ứng dụng.
  • Play App Signing quản lý tập trung các khóa phân phối qua Google Play Console.
  • Xác minh chữ ký khi cài đặt chặn các cuộc tấn công thay thế: không khớp chứng chỉ = lỗi INSTALL_FAILED.
  • Bảo mật khóa: khóa riêng cho mỗi ứng dụng, hiệu lực 25+ năm, bản sao ngoại tuyến, không khóa trong kho lưu trữ.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm