Android签名的那些事

作者: WaitingAnd | 来源:发表于2017-01-04 18:20 被阅读0次

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

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

    Build Variants

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

    debug.keystore位置

    微信签名工具


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

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

    微信签名工具下载

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


    微信签名工具

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

    keytool工具


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

    keytool.exe

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

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

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

    META-INF

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

    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签名的那些事

        本文链接:https://www.haomeiwen.com/subject/axoovttx.html