3 votes

Comment vérifier que l'application a été signée par mon certificat ?

Comment puis-je vérifier si la signature de mon application correspond à la signature du certificat que j'ai utilisé pour la signer ?

C'est ainsi que je devrais pouvoir obtenir l'empreinte des certificats :

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();
    }

C'est ainsi que je devrais pouvoir obtenir l'empreinte digitale de mon certificat :

keytool -v -list -keystore filenameandpath

Mon problème est que les deux donnent des résultats différents. Quelqu'un pourrait-il m'indiquer ce que je fais de travers ?

7voto

Yojimbo Points 3819

Vous calculez le hachage MD5 des mauvaises données. L'empreinte digitale d'un certificat est un hachage (MD5, SHA1, SHA256, etc.) du certificat brut. C'est-à-dire que vous devriez calculer le hachage de ces octets :

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

Par exemple, ce qui suit calcule une empreinte SHA1, changez simplement SHA1 en MD5 si vous préférez.

    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;
}

1voto

akuzma Points 1570

Vous pouvez ouvrir l'apk comme un fichier zip et filtrer le texte ascii du contenu binaire de META-INF/CERT.RSA et vérifier que c'est bien vous qui l'avez singé.


essayez :

final void  initVerify(Certificate certificate)

de : http://developer.Android.com/reference/java/security/Signature.html

0voto

mah Points 21457

Utilisez votre code pour collecter l'empreinte digitale sur le dispositif en mode "test" -- ce qui signifie que vous disposez d'un code temporaire pour émettre cette empreinte digitale vers le journal (ou ailleurs). Assurez-vous de tester ceci en utilisant votre clé de signature de production, et non la clé de débogage !

Une fois que vous le savez du point de vue de l'appareil, vous pouvez retirer le code temporaire et le comparer ailleurs à ce que vous avez déterminé précédemment comme étant la clé.

Sachez toutefois que vous faites probablement cela pour empêcher quelqu'un de modifier votre application et de la re-signer avec une autre clé, mais quelqu'un qui a la capacité de le faire a également la capacité de modifier la vérification de votre clé. Ce problème peut être résolu par une obscurcissement supplémentaire, mais vous devrez trouver votre propre solution pour minimiser les risques qu'un attaquant sache ce qu'il faut rechercher.

0voto

user3759312 Points 1

Le code ci-dessous :

 c.getPublicKey().getEncoded()

cela devrait être comme ceci

 c.getEncoded()

Je pense que la vérification du md5 par keytool vérifie le fichier de certificat, pas la clé publique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X