由于本人能力有限,文中若有错误之处,欢迎指正。
转载请注明出处:http://www.jianshu.com/p/8edd0b70077f
在开发中,我们运行一个项目,默认使用的构建类型为 debug,当然也可以在Build Variants
中修改。如下:
在使用 debug 类型构建项目时,默认使用的签名文件为debug.keystore
,该签名文件有效期为365天,该文件位于 <user>/.android/debug.keystore
(Windows为例)。如下:
微信签名工具
目前在申请使用第三方SDK时,一般都需要提供包名,签名信息(MD5,SHA1等)。
以微信为例,其专门提供了获取安装到手机的第三方应用签名的apk包,方便开发者用来获取签名信息。微信签名工具下载地址
如下图,输入应用的包名,即可获取对应的应用签名信息。
以上是通过微信提供的工具的方式获取应用签名信息。
keytool工具
其实,只要我们安装了JDK,完全可以使用JDK所提供的keytool.exe
工具获取签名信息。该工具位于<java_home>/bin/keytool.exe
(如果配置了环境变量,可以直接使用keytool
命令)。输入keytool -list -v -keystore 签名文件路径
,即可查看签名信息。如下:
经过对比,我们发现微信获取的签名信息其实就是证书指纹的 MD5 值(去掉中间的:
,并且所有字母小写)。申请使用第三方 SDK 时,要求提供的 SHA1 值,也可以通过这种方式提供。
那么如何获取一个 apk 的签名信息呢?
我们解压一个 apk 文件,会发现META-INF
文件夹,这个文件夹里面保存的就是应用签名相关的信息。如下:
进而我们可以得到里面的CERT.RSA
文件。使用keytool.exe
工具,输入keytool -printcert -file CERT.RSA文件路径
就可以获取 apk 的签名信息。如下:
微信签名工具的原理
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();
}
}