Reputation:
I would like to check code integrity where where an attacker could modify an Android application package (APK) without proper authorization.
I have created functions that check SHA1, if it the same as mine from local.properties
private fun checkIntegrity() {
val expectedSignature = BuildConfig.PROD_SHA1_SIGNATURE
if (integrityChecker.checkCodeIntegrity(expectedSignature)) {
} else {
nonFatalLogger.logNonFatal(Exception(integrityChecker.getErrorMessageIntegrity()))
integrityChecker.finishApplication()
}
}
fun checkCodeIntegrity(expectedSignature: String): Boolean {
val actualSignature = getCertificateSHA1Fingerprint()
return actualSignature == expectedSignature
}
private fun getCertificateSHA1Fingerprint(): String? {
val pm: PackageManager = context.packageManager
val packageName: String = context.packageName
var signatures: Array<Signature>? = null
try {
signatures = with(pm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
getPackageInfoCompat(packageName, PackageManager.GET_SIGNING_CERTIFICATES)
.signingInfo
.apkContentsSigners
} else {
getPackageInfoCompat(packageName, PackageManager.GET_SIGNATURES)
.signatures
}
}
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
val cert = signatures?.get(0)?.toByteArray()
val input: InputStream = ByteArrayInputStream(cert)
var cf: CertificateFactory? = null
try {
cf = CertificateFactory.getInstance("X509")
} catch (e: CertificateException1) {
e.printStackTrace()
}
var c: X509Certificate? = null
try {
c = cf?.generateCertificate(input) as X509Certificate
} catch (e: CertificateException1) {
e.printStackTrace()
}
var hexString: String? = null
try {
val md = MessageDigest.getInstance(SHA1_NAME)
val publicKey = md.digest(c?.encoded)
hexString = byte2HexFormatted(publicKey)
} catch (e1: NoSuchAlgorithmException) {
e1.printStackTrace()
} catch (e: CertificateEncodingException) {
e.printStackTrace()
}
return hexString
}
Everything works fine, but when I create Signed Bundle/APK
or generate my app on bitrise it goes to the else function finishApplication
which means for me SHA1 is not the same as generated before? Why?
I have generated SHA1 from my release-keystore or productionRelease
build and it is correct, but after launch apk from Signed Bundle
it is not and I quite do not understand that.
Of course I could manage it, to lognotfatal
error to firebase with my proper SHA1 from signed bundle apk, but first I would like to understand it and maybe instead of two SHA values in local.properties, use just one.
Upvotes: 0
Views: 113