Java解析apk的签名,是表示这个apk的唯一作者的。里面涉及到很多什么 私钥 公钥 之类的东西,反正是涉及的很严密,在网上的相关文档也不是很少。 说白了,就是不能轻易的让其他人去修改的你的签名,不能去修改的apk。要是修改了,签名就会发生变化,知道不是原生作者。我们就是为了判断一个apk的包,是否是原来的作者,就写一个Java的自动解析apk的签名的东西。获取到之后,当下次软件升级更新的时候,判断签名是否匹配,否则,不予以升级、更新之类的。
网上写Java获取apk签名的方式主要有两种,
(1)、解压apk包,在里面找到一个.RSA文件,然后进行解析。
import sun.security.pkcs.PKCS7;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
public class SignApk {
public static X509Certificate readSignatureBlock(InputStream in) throws IOException, GeneralSecurityException {
PKCS7 pkcs7 = new PKCS7(in);
return pkcs7.getCertificates()[0];
}
public static void main(String[] args) throws FileNotFoundException, IOException, GeneralSecurityException {
X509Certificate publicKey = readSignatureBlock(new FileInputStream("./CERT.RSA"));
System.out.println("issuer:" + publicKey.getIssuerDN());
System.out.println("subject:" + publicKey.getSubjectDN());
System.out.println(publicKey.getPublicKey());
}
}
如下:
issuer:CN=Sodino
subject:CN=SodinoChen
Sun RSA public key, 1024 bits
modulus: 154308594144468705348294760484396264219304223307125368116140288659005422830114898674784044956357283073098453132761265419031547660249768235885852151387544779929680291539693130807734777897342583741160281523340554669518353638961667015615312475350767041053961957188628650343640790505255765999004862716823611888529
public exponent: 65537
(2)、就是利用cmd指令,也就是 jarsigner 指令获取。
jarsigner -verify -verbose -certs <your_apk_path.apk>
由于是我们上传apk,如果解压解析的话,就有点过分了,破坏了apk不说,还要删除解压之后的文件,有些繁琐,而且操作复杂,不适合我们。所以,决定使用第二种方法,就是cmd指令, 然后,让java去调用 cmd的指令,然后打印返回信息进行解析。获取自己想要的信息。
现在是贴出来最主要的方法:
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
public class newtest3 {
public static void main(String[] arg)
{
String apkUrl = "C:\\Users\\Administrator\\Desktop\\com.taobao.taobao_淘宝.apk";
String apkUrl1 = "C:\\Users\\Administrator\\Desktop\\sign.apk";
String result = getSingle(apkUrl);
String result2 = getSingle(apkUrl1);
System.out.println(result+"~"+result2);
}
public static String getSingle(String apkUrl){
Process p;
//test.bat中的命令是ipconfig/all
String cmd = "jarsigner -verify -verbose -certs " + apkUrl;
// String cmd="jarsigner -verify -verbose -certs C:\\Users\\Administrator\\Desktop\\PandaClient.apk";
String resultstr = null;
try
{
//执行命令
p = Runtime.getRuntime().exec(cmd);
//取得命令结果的输出流
InputStream fis=p.getInputStream();
//用一个读输出流类去读
//用缓冲器读行
BufferedReader br=new BufferedReader( new InputStreamReader(fis,"GB2312"));
String line=null;
//直到读完为止
int i = 0;
while((line=br.readLine())!=null)
{
if(line.contains("X.509")){ //解析符合自己需要的內容,获取之后,直接返回。
// System.out.println(line);
resultstr = line;
break;
}
i++;
}
}
catch (IOException e)
{
e.printStackTrace();
}
return resultstr.replace(" X.509, ", "");
}
}