Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify that app was signed by my certificate?

How do I check if the signature of my app matches the signature of the certificate that I used to sign it?

This is how I should be able to get the certificates fingerprint:

public String getCertificateFingerprint() throws NameNotFoundException, CertificateException, NoSuchAlgorithmException {
        PackageManager pm = context.getPackageManager();
        String packageName =context.getPackageName();

        int flags = PackageManager.GET_SIGNATURES;

        PackageInfo packageInfo = null;

        packageInfo = pm.getPackageInfo(packageName, flags);
        Signature[] signatures = packageInfo.signatures;

        byte[] cert = signatures[0].toByteArray();

        InputStream input = new ByteArrayInputStream(cert);

        CertificateFactory cf = null;
        cf = CertificateFactory.getInstance("X509");

        X509Certificate c = null;
        c = (X509Certificate) cf.generateCertificate(input);

        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] publicKey = md.digest(c.getPublicKey().getEncoded());

        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < publicKey.length; i++) {
            String appendString = Integer.toHexString(0xFF & publicKey[i]);
            if (appendString.length() == 1)
                hexString.append("0");
            hexString.append(appendString);
        }

        return hexString.toString();
    }

This is how I should be able to get the fingerprint of my certificate:

keytool -v -list -keystore filenameandpath

My problem is, that these two give back different results. Could someone point out what I'm screwing up?

like image 699
Tamas Avatar asked Jan 18 '26 10:01

Tamas


2 Answers

You are computing the MD5 hash of the wrong data. The fingerprint of a certificate is a hash (MD5, SHA1, SHA256, etc.) of the raw certificate. I.e., you should be computing the hash of these bytes:

byte[] cert = signatures[0].toByteArray();

E.g., the following computes a SHA1 fingerprint, just change SHA1 to MD5 if you prefer.

    public String computeFingerPrint(final byte[] certRaw) {

    String strResult = "";

    MessageDigest md;
    try {
        md = MessageDigest.getInstance("SHA1");
        md.update(certRaw);
        for (byte b : md.digest()) {
            strAppend = Integer.toString(b & 0xff, 16);
            if (strAppend.length() == 1)
                strResult += "0";
            strResult += strAppend;
        }
        strResult = strResult.toUpperCase(DATA_LOCALE);
    }
    catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
    }

    return strResult;
}
like image 90
Yojimbo Avatar answered Jan 21 '26 03:01

Yojimbo


You can open the apk as a zip file and filter the ascii text from the binary content of META-INF/CERT.RSA and check there is it you who singed it.


try:

final void  initVerify(Certificate certificate)

from: http://developer.android.com/reference/java/security/Signature.html

like image 41
akuzma Avatar answered Jan 21 '26 02:01

akuzma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!