Skip to content

Instantly share code, notes, and snippets.

@athkalia
Last active April 12, 2018 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save athkalia/e48851a3b14264b099f4e5fb302667b2 to your computer and use it in GitHub Desktop.
Save athkalia/e48851a3b14264b099f4e5fb302667b2 to your computer and use it in GitHub Desktop.
private String calculateHash() {
try {
String certificateFingerprint = getCertificateSha1Fingerprint().toLowerCase(Locale.UK);
MessageDigest digest = MessageDigest.getInstance(SHA_256);
String packageName = context.getPackageName();
Timber.d("Calculating hash for package name %s", packageName);
digest.update(packageName.getBytes(UTF_8));
digest.update(certificateFingerprint.getBytes(UTF_8));
return HexEncoder.bytesToHexString(digest.digest());
} catch (NoSuchAlgorithmException e) {
Timber.e(e);
throw new RuntimeException("Environment does not support sha-256 digest.");
// Running in an environment that does not support sha-256 or is missing utf-8. Shouldn't ever happen.
}
}
// Note that there's a vulnerability with this before API 19, where someone can inject fake signatures in an app.
// When using this for API < 19 you should check all signatures.
public String getCertificateSha1Fingerprint() {
try {
Signature[] signatures = context.getPackageManager()
.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
Signature firstSig = signatures[0];
if (firstSig == null) {
throw new RuntimeException("Unable to verify APK signature - no signatures present");
}
byte[] rawCert = firstSig.toByteArray();
InputStream certStream = new ByteArrayInputStream(rawCert);
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
X509Certificate x509Cert = (X509Certificate) certFactory.generateCertificate(certStream);
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
byte[] digest = sha1.digest(x509Cert.getEncoded());
return HexEncoder.bytesToHexString(digest);
} catch (PackageManager.NameNotFoundException | CertificateException e) {
Timber.e(e);
throw new RuntimeException("The app must be signed!");
} catch (NoSuchAlgorithmException e) {
Timber.e(e);
throw new RuntimeException("Environment does not support SHA1 digests!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment