Android签名的那些事

由于本人能力有限,文中若有错误之处,欢迎指正。
转载请注明出处:http://www.jianshu.com/p/8edd0b70077f

在开发中,我们运行一个项目,默认使用的构建类型为 debug,当然也可以在Build Variants中修改。如下:

Android签名的那些事_第1张图片
Build Variants

在使用 debug 类型构建项目时,默认使用的签名文件为debug.keystore,该签名文件有效期为365天,该文件位于 /.android/debug.keystore(Windows为例)。如下:

Android签名的那些事_第2张图片
debug.keystore位置

微信签名工具


目前在申请使用第三方SDK时,一般都需要提供包名,签名信息(MD5,SHA1等)。

以微信为例,其专门提供了获取安装到手机的第三方应用签名的apk包,方便开发者用来获取签名信息。微信签名工具下载地址

Android签名的那些事_第3张图片
微信签名工具下载

如下图,输入应用的包名,即可获取对应的应用签名信息。


Android签名的那些事_第4张图片
微信签名工具

以上是通过微信提供的工具的方式获取应用签名信息。

keytool工具


其实,只要我们安装了JDK,完全可以使用JDK所提供的keytool.exe工具获取签名信息。该工具位于/bin/keytool.exe(如果配置了环境变量,可以直接使用keytool命令)。输入keytool -list -v -keystore 签名文件路径,即可查看签名信息。如下:

Android签名的那些事_第5张图片
keytool.exe

经过对比,我们发现微信获取的签名信息其实就是证书指纹的 MD5 值(去掉中间的:,并且所有字母小写)。申请使用第三方 SDK 时,要求提供的 SHA1 值,也可以通过这种方式提供。

那么如何获取一个 apk 的签名信息呢?

我们解压一个 apk 文件,会发现META-INF文件夹,这个文件夹里面保存的就是应用签名相关的信息。如下:

Android签名的那些事_第6张图片
META-INF

进而我们可以得到里面的CERT.RSA文件。使用keytool.exe工具,输入keytool -printcert -file CERT.RSA文件路径 就可以获取 apk 的签名信息。如下:

Android签名的那些事_第7张图片
CERT.RSA

微信签名工具的原理



public class MainActivity extends AppCompatActivity {

    // ...

    private void getSignature() {
        Signature[] rawSignature = getRawSignature(MainActivity.this, "包名"); // 设置应用的包名

        for (Signature signature : rawSignature) {
            String messageDigest = MD5.getMD5String(signature.toByteArray()); // 获取到签名信息
            textView.setText(messageDigest);
        }
    }

    private Signature[] getRawSignature(Context context, String packageName) {
        if ((packageName == null) || (packageName.length() == 0)) {
            return null;
        }
        PackageManager localPackageManager = context.getPackageManager();
        PackageInfo localPackageInfo;
        try {
            localPackageInfo = localPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
            if (localPackageInfo == null) {
                return null;
            }
        } catch (PackageManager.NameNotFoundException localNameNotFoundException) {
            return null;
        }
        return localPackageInfo.signatures;
    }


}

public class MD5 {

    private static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6',  '7', '8',
            '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    private static MessageDigest messagedigest = null;

    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            System.err.println("MessageDigest初始化失败");
            e.printStackTrace();
        }
    }

    public static String getMD5String(byte[] bytes) {
        messagedigest.update(bytes);
        byte[] digest = messagedigest.digest();
        return bufferToHex(digest, 0, digest.length);
    }

    private static String bufferToHex(byte[] bytes, int m, int n) {
        StringBuilder sb = new StringBuilder(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            char c0 = hexDigits[(bytes[l] & 0xf0) >> 4];
            char c1 = hexDigits[bytes[l] & 0xf];
            sb.append(c0);
            sb.append(c1);
        }
        return sb.toString();
    }

}

你可能感兴趣的:(Android签名的那些事)