歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java 解析 apk 的簽名

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為開頭的。當獲取到之後,就立刻跳出循環。處理獲取到的字符串,然後直接返回就好了。

就是這些了,希望這些代碼對讀者有幫助哈。

Copyright © Linux教程網 All Rights Reserved