package com.qianfandu.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* 应用签名相关工具类
*
* Created by linchaolong on 2016/5/3.
*/
public class SignatureUtils {
public static final String TAG = SignatureUtils.class.getSimpleName();
public static void checkSign(Context context) {
String certMD5 = SignatureUtils.getCertMD5(context);
try {
InputStream signIn = context.getAssets().open("sign.bin");
if(signIn==null){
return;
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buff = new byte[10240];
for (int len; (len = signIn.read(buff)) != -1; ) {
output.write(buff, 0, len);
}
String signData = new String(ApkToolPlus.decrypt(output.toByteArray()));
// Log.e(TAG, "certMD5 = " + certMD5);
// Log.e(TAG, "sign.bin = " + signData);
if(!certMD5.equals(signData)){
// 签名不匹配,不能运行app,防止二次打包
throw new RuntimeException("signature is not match!!! can't run app.");
}
} catch (Exception e) {
throw new RuntimeException("check sign error!!! " + e.getMessage());
}
}
public static String getCertMD5(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
if (signs.length > 0) {
return getCertMD5(signs[0].toByteArray());
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String getCertMD5(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
String certMD5 = md5Digest(cert.getEncoded());
return certMD5;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static void parseSignature(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
String pubKey = cert.getPublicKey().toString();
String signNumber = cert.getSerialNumber().toString();
// System.out.println("signName:" + cert.getSigAlgName());
// System.out.println("pubKey:" + pubKey);
// System.out.println("signNumber:" + signNumber);
// System.out.println("subjectDN:" + cert.getSubjectDN().toString());
// System.out.println("certMd5 :" + md5Digest(cert.getEncoded()));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String md5Digest(byte[] input) throws IOException {
MessageDigest digest = getDigest("Md5");
digest.update(input);
return getHexString(digest.digest());
}
public static String getHexString(byte[] digest) {
BigInteger bi = new BigInteger(1, digest);
return String.format("%032x", bi);
}
public static MessageDigest getDigest(String algorithm) {
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.getMessage());
}
}
}