Android only allows the installation of specified signature apk

Requirement: Only specific signature apk is allowed to install, other signature apk is prohibited to install.

One, transplant the following code

commit 814c25ddd422f8f44a3de9451ef25e296a298ea0
Author: shenhb <[email protected]>
Date:   Thu Feb 20 11:31:19 2020 +0800
仅允许安装指定签名apk,通过属性ro.signature配置签名sha1值
index b7171ba..414a064 100755
--- a/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -355,6 +355,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.GZIPInputStream;
+import java.util.Locale;

/**

  • Keep track of all those APKs everywhere.
    @@ -18605,6 +18606,37 @@ public class PackageManagerService extends IPackageManager.Stub
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }
  • // Add by [email protected], for only allow the specified signature apk.

  • private static String getFingerprint(Signature signature, String hashAlgorithm) {

  •    if (signature == null) {
    
  •        return null;
    
  •    }
    
  •    try {
    
  •        MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);
    
  •        return toHexadecimalString(digest.digest(signature.toByteArray()));
    
  •    } catch (NoSuchAlgorithmException e) {
    
  •        // ignore
    
  •    }
    
  •    return null;
    
  • }

  • private static String toHexadecimalString(byte[] value) {

  •    StringBuffer sb = new StringBuffer();
    
  •    int len = value.length;
    
  •    for (int i = 0; i < len; i++) {
    
  •        int num = ((int) value[i]) & 0xff;
    
  •        if (num < 0x10) {
    
  •            sb.append('0');
    
  •        }
    
  •        sb.append(Integer.toHexString(num));
    
  •        if (i < len - 1) {
    
  •            sb.append(':');
    
  •        }
    
  •    }
    
  •    return sb.toString().toUpperCase(Locale.US);
    
  • }

  • // Add end

  • private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
    try {
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “installPackage”);
    @@ -18771,6 +18803,20 @@ public class PackageManagerService extends IPackageManager.Stub
    return;
    }

  •    // Add by [email protected], for only allow the specified signature apk.
    
  •    String customSignature = SystemProperties.get("ro.signature", "");
    
  •    if (!TextUtils.isEmpty(customSignature)) {
    
  •        final Signature[] signatures = pkg.mSignatures;
    
  •        Slog.d(TAG, "installPackageLI, Signature fingerprint "
    
  •                + getFingerprint(signatures[0], "SHA-1"));
    
  •        if (!getFingerprint(signatures[0], "SHA-1").equals(customSignature)) {
    
  •            res.setError(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
    
  •                    "Signature verification failed");
    
  •            return;
    
  •        }
    
  •    }
    
  •    // Add end
    
  •    // Get rid of all references to package scan path via parser.
       pp = null;
       String oldCodePath = null;
    

Two, attribute configuration signature sha1

Considering the versatility of the scheme, the signature is configured through attributes. If the attribute is not configured, the Android default logic is used to allow all apks to be installed. After the properties are configured, only the apk matching this signature is allowed to install.

2.1 Obtain the signature sha1 and
decompress the apk file, and mention META-INF/CERT.RSA (the public key of the signature file).
Execute the following command to get the sha1 value of the public key.
F:\download
λ keytool -printcert -file CERT.RSA
owner: CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=china
Publisher: CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=china
Serial number: xxxxxxx
Validity period start date: Sun Feb 11 14:38:48 CST 2018, expiration date: Thu Feb 05 14:38:48 CST 2043
Certificate fingerprint:
MD5: 13:8A:22:DC:6E:6C:BA:27:42:8D:9F:C5:0D:D2:4E:14
SHA1: 31:4E:FC:8C:68:FA:7E:F4 :14:E7:27:C3:A9:C4:9C:F1:AB:1C:64:C2
SHA256: 63:E0:0A:FF:45:7C:03:97:F5:27:64:C5: D4:DA:BD:8A:2E:63:40:E7:31:A3:C8:3D:FB:03:00:2A:9F:BE:71:EF
Signature Algorithm Name: SHA256withRSA
Version: 3

Extension:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: C9 41 D4 8D F0 58 FF E2 EE EF 7E 5E 3B 9D DA 44 .A…X…^;…D
0010: 40 E5 DF FC @…
]
]
2.2 配置属性
ro.signature=31:4E:FC:8C:68:FA:7E:F4:14:E7:27:C3:A9:C4:9C:F1:AB:1C:64:C2

Three, verification

The verification result is as follows. The installation of the apk with a non-specified signature fails, and "Signature verification failed" is displayed, and the apk with the specified signature is successfully installed.

λ adb install 001.apk
adb: failed to install 001.apk: Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Signature verification failed]

λ adb install 002.apk
Success

Guess you like

Origin blog.csdn.net/qq_39453420/article/details/113120896