Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
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);
return HexEncoder.bytesToHexString(digest.digest());
} catch (NoSuchAlgorithmException 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) {
throw new RuntimeException("The app must be signed!");
} catch (NoSuchAlgorithmException 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