2014-01-22 63 views
2

我正在使用此代码,但它显示了同一应用程序的哈希代码。 请帮我解决。从内存中安装的apk文件生成哈希

File file = new File(getApplicationContext().getPackageCodePath()); 
    String outputTxt= ""; 
     String hashcode = null; 

    try { 

     FileInputStream input = new FileInputStream(file); 

     ByteArrayOutputStream output = new ByteArrayOutputStream(); 
     byte [] buffer = new byte [65536]; 
     int l; 


      while ((l = input.read (buffer)) > 0) 
       output.write (buffer, 0, l); 

      input.close(); 
      output.close(); 

      byte [] data = output.toByteArray(); 

      MessageDigest digest = MessageDigest.getInstance("SHA-1"); 

      byte[] bytes = data; 

      digest.update(bytes, 0, bytes.length); 
      bytes = digest.digest(); 

      StringBuilder sb = new StringBuilder(); 

      for(byte b : bytes) 
      { 
       sb.append(String.format("%02X", b)); 
      } 

      hashcode = sb.toString(); 





    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

现在我想读(假设它会被* .apk文件)我目前的Android应用程序的安装的应用程序文件,从文件中读取的字节数组,并产生散列值。

在此先感谢。

回答

3

这是最好的解决方案。

首先你必须通过.apk文件的路径。

  private CharSequence getHash(String sourceDir) { 
      // TODO Auto-generated method stub 

      File file = new File(packageInfo.applicationInfo.sourceDir); 
     String outputTxt= ""; 
      String hashcode = null; 

     try { 

     FileInputStream input = new FileInputStream(file); 

     ByteArrayOutputStream output = new ByteArrayOutputStream(); 
     byte [] buffer = new byte [65536]; 
     int l; 


       while ((l = input.read (buffer)) > 0) 
        output.write (buffer, 0, l); 

        input.close(); 
       output.close(); 

       byte [] data = output.toByteArray(); 

       MessageDigest digest = MessageDigest.getInstance("SHA-1"); 

      byte[] bytes = data; 

      digest.update(bytes, 0, bytes.length); 
      bytes = digest.digest(); 

      StringBuilder sb = new StringBuilder(); 

      for(byte b : bytes) 
      { 
       sb.append(String.format("%02X", b)); 
      } 

      hashcode = sb.toString(); 


     } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 



      return hashcode; 
     } 
1
public void buttonAppClick() { 
    final PackageManager pm = getActivity().getPackageManager(); 
    //get a list of installed apps. 
    List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA); 
    outputTextView.setText(""); 
    for (ApplicationInfo packageInfo : packages) { 
     try { 
      String packageName = packageInfo.packageName; 
      outputTextView.append("Apk Path : " + packageInfo.sourceDir + "\n"); 
      PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 

      Signature sig = pi.signatures[0]; 
      String md5Fingerprint = doFingerprint(sig.toByteArray(), "MD5"); 
      Log.d(TAG_HOME, "MD5 : " + packageInfo.sourceDir + md5Fingerprint); 
      outputTextView.append("MD5 : " + md5Fingerprint + "\n"); 
      outputTextView.append("\n"); 
     } 
     catch (Exception e) { 
      Log.e(TAG_HOME, e.getMessage()); 
     } 
    } 
} 

protected static String doFingerprint(byte[] certificateBytes, String algorithm) 
     throws Exception { 
    MessageDigest md = MessageDigest.getInstance(algorithm); 
    md.update(certificateBytes); 
    byte[] digest = md.digest(); 

    String toRet = ""; 
    for (int i = 0; i < digest.length; i++) { 
     if (i != 0) 
      toRet += ":"; 
     int b = digest[i] & 0xff; 
     String hex = Integer.toHexString(b); 
     if (hex.length() == 1) 
      toRet += "0"; 
     toRet += hex; 
    } 
    return toRet; 
} 

首先我从PackageInfo 签名转换是签名字节数组,然后使用doFringerPrint函数来获取Android应用的MD5。