Search code examples
androidsecurityencryptionx509certificateandroid-build

android certificate serial number check at app launch?


I inherited an android app that has some security-related code that seems to basically be a no-op and that I'd like to remove. However, I'm concerned that my assessment of it as a no-op may be incorrect. The app sub-classes Application and, in its onCreate() method, gets the serial number of the certificate that the app was signed with:

ByteArrayInputStream bais = new ByteArrayInputStream(context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0].toByteArray()));

X509Certificate cert = CertificateFactory.getInstance("X509").generateCertificate(bais);

BigInteger sn = cert.getSerialNumber();

It then computes a hash of this value and compares it to an expected value that's embedded in a Java class as a byte[]. If the hashes don't match it throws an exception, crashing the app.

What this seems to prevent is someone stealing our source code, building the app and signing it themselves, then trying to install and run it. However, if someone has the source, they can simply remove the check at app launch. (Or change the embedded hash value to match the serial number of their certificate).

Is that accurate? Or is there some reason I'm missing that this code is useful?


Solution

  • I don't think it's to protect people from stealing your source code. It's to prevent people from replacing all the assets, thereby rebranding the app as their own, then re-signing it and putting it in the play store as their own.

    However, the program shouldn't be verifying the serial number, which is easily modified. It should be verifying the signature.

    If someone goes to the trouble of decompiling the app, as you said, they can remove that security check.

    It's just another hoop for a cracker to jump through. Consider keeping it, but be sure to check the signature, not just the serial number.