3

アプリの署名が、署名に使用した証明書の署名と一致するかどうかを確認するにはどうすればよいですか?

これは、証明書のフィンガープリントを取得できる方法です。

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

これは、証明書のフィンガープリントを取得できる方法です。

keytool -v -list -keystore filenameandpath

私の問題は、これら2つが異なる結果を返すことです。誰かが私が台無しにしていることを指摘できますか?

4

4 に答える 4

7

間違ったデータの MD5 ハッシュを計算しています。証明書のフィンガープリントは、未加工の証明書のハッシュ (MD5、SHA1、SHA256 など) です。つまり、これらのバイトのハッシュを計算する必要があります。

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

たとえば、次は SHA1 フィンガープリントを計算します。必要に応じて SHA1 を MD5 に変更します。

    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;
}
于 2013-07-09T15:58:13.620 に答える
1

apk を zip ファイルとして開き、META-INF/CERT.RSA のバイナリ コンテンツから ascii テキストをフィルター処理して、それを歌ったのが自分であるかどうかを確認できます。


試す:

final void  initVerify(Certificate certificate)

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

于 2013-07-09T13:04:11.533 に答える
0

以下のコード:

 c.getPublicKey().getEncoded()

このようにする必要があります

 c.getEncoded()

keytoolによるmd5チェックは、公開鍵ではなく証明書ファイルのチェックだと思います

于 2014-06-20T08:09:28.017 に答える
0

「テスト」モードでデバイスの指紋を収集するためにコードを使用します。つまり、その指紋をログ (または他の場所) に出力するための一時的なコードがあることを意味します。デバッグ キーではなく、実稼働署名キーを使用してこれをテストしてください。

デバイスの観点からわかったら、一時コードを削除し、以前にキーであると判断したものと比較できます。

おそらく、誰かがアプリを変更して別のキーで再署名するのを防ぐためにこれを行っていることに注意してください。ただし、それを実行できる人は、キー チェックを変更することもできます。これは難読化を追加することで対処できる問題ですが、攻撃者が何を探すべきかを知る可能性を最小限に抑えるために、独自の解決策を考え出す必要があります。

于 2013-07-09T13:03:21.610 に答える