1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
fun apkVerifier(input: String) { launch(Dispatchers.IO) { updateApkVerifierState(UIState.Loading) val list = ArrayList<model.ApkVerifier>() val inputFile = File(input) val path = inputFile.path val name = inputFile.name val verifier: ApkVerifier = ApkVerifier.Builder(inputFile).build() try { val result = verifier.verify() var error = "" val isSuccess = result.isVerified
result.errors.filter { it.issue == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY } .forEach { error += it.toString() + "\n" }
if (result.v1SchemeSigners.isNotEmpty()) { for (signer in result.v1SchemeSigners) { val cert = signer.certificate ?: continue if (signer.certificate.type == "X.509") { val subject = cert.subjectX500Principal.name val validFrom = cert.notBefore.toString() val validUntil = cert.notAfter.toString() val publicKeyType = (cert.publicKey as? RSAPublicKey)?.algorithm ?: "" val modulus = (cert.publicKey as? RSAPublicKey)?.modulus?.toString(10) ?: "" val signatureType = cert.sigAlgName val md5 = getThumbPrint(cert, "MD5") ?: "" val sha1 = getThumbPrint(cert, "SHA-1") ?: "" val sha256 = getThumbPrint(cert, "SHA-256") ?: "" val apkVerifier = model.ApkVerifier(1, subject, validFrom, validUntil, publicKeyType, modulus, signatureType, md5, sha1, sha256) list.add(apkVerifier) } signer.errors.filter { it.issue == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY } .forEach { error += it.toString() + "\n" } } }
if (result.v2SchemeSigners.isNotEmpty()) { for (signer in result.v2SchemeSigners) { val cert = signer.certificate ?: continue if (signer.certificate.type == "X.509") { val subject = cert.subjectX500Principal.name val validFrom = cert.notBefore.toString() val validUntil = cert.notAfter.toString() val publicKeyType = (cert.publicKey as? RSAPublicKey)?.algorithm ?: "" val modulus = (cert.publicKey as? RSAPublicKey)?.modulus?.toString(10) ?: "" val signatureType = cert.sigAlgName val md5 = getThumbPrint(cert, "MD5") ?: "" val sha1 = getThumbPrint(cert, "SHA-1") ?: "" val sha256 = getThumbPrint(cert, "SHA-256") ?: "" val apkVerifier = model.ApkVerifier(2, subject, validFrom, validUntil, publicKeyType, modulus, signatureType, md5, sha1, sha256) list.add(apkVerifier) } signer.errors.filter { it.issue == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY } .forEach { error += it.toString() + "\n" } } }
if (result.v3SchemeSigners.isNotEmpty()) { for (signer in result.v3SchemeSigners) { val cert = signer.certificate ?: continue if (signer.certificate.type == "X.509") { val subject = cert.subjectX500Principal.name val validFrom = cert.notBefore.toString() val validUntil = cert.notAfter.toString() val publicKeyType = (cert.publicKey as? RSAPublicKey)?.algorithm ?: "" val modulus = (cert.publicKey as? RSAPublicKey)?.modulus?.toString(10) ?: "" val signatureType = cert.sigAlgName val md5 = getThumbPrint(cert, "MD5") ?: "" val sha1 = getThumbPrint(cert, "SHA-1") ?: "" val sha256 = getThumbPrint(cert, "SHA-256") ?: "" val apkVerifier = model.ApkVerifier(3, subject, validFrom, validUntil, publicKeyType, modulus, signatureType, md5, sha1, sha256) list.add(apkVerifier) } signer.errors.filter { it.issue == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY } .forEach { error += it.toString() + "\n" } } }
if (isSuccess || list.isNotEmpty()) { val apkVerifierResult = ApkVerifierResult(isSuccess, path, name, list) updateApkVerifierState(UIState.Success(apkVerifierResult)) } else { if (error.isBlank()) { error = "APK签名验证失败" } updateApkVerifierState(UIState.Error(error)) } } catch (e: Exception) { updateApkVerifierState(UIState.Error(e.message ?: "APK签名验证失败")) e.printStackTrace() } if (apkVerifierState is UIState.Error) { delay(1000) updateApkVerifierState(UIState.WAIT) } } }
private fun getThumbPrint(cert: X509Certificate?, type: String?): String? { val md = MessageDigest.getInstance(type) val der: ByteArray = cert?.encoded ?: return null md.update(der) val digest = md.digest() return hexify(digest) }
private fun hexify(bytes: ByteArray): String { val hexDigits = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') val buf = StringBuilder(bytes.size * 3) for (aByte in bytes) { buf.append(hexDigits[aByte.toInt() and 0xf0 shr 4]) buf.append(hexDigits[aByte.toInt() and 0x0f]) if (bytes.indexOf(aByte) != bytes.size - 1) { buf.append(':') } } return buf.toString() }
|