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, ", "");
}
}
以上主要的代碼是, 邊界一個在cmd 要執行的 一個字符串,路徑別忘了轉移字符啊。 然後讓java去執行cmd,獲取返回的內容。 匹配,當獲得自己想要的 我的字符串開頭是
X.509為開頭的。當獲取到之後,就立刻跳出循環。處理獲取到的字符串,然後直接返回就好了。
就是這些了,希望這些代碼對讀者有幫助哈。