android apk 防止反编译技术第五篇-完整性校验(转)

1、完整性校验原理java

所谓完整性校验就是咱们用各类算法来计算一个文件的完整性,防止这个文件被修改。其中经常使用的方法就是计算一个文件的CRC32的值或者计算一个文件的哈希值。咱们在防止apk被反编译的方法中也能够采用这种方法。咱们知道apk生成的classes.dex主要由java文件生成的,它是整个apk的逻辑实现。因此咱们能够对classes.dex文件进行完整性校验,来保证整个程序的逻辑不被修改。若是咱们想要保证整个apk文件的完整性,也能够对整个apk文件进行完整性校验。下面咱们分别来实现对classes.dex文件和apk文件的完整性校验。 linux

2、用crc32对classes.dex文件的完整性进行校验算法

(1)能够打印出来咱们的apk生的classes.dex文件的crc32的值,代码以下:服务器

?网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MainActivity extendsActivity {
 
@Override
 
protected void onCreate(BundlesavedInstanceState) {
 
     super .onCreate(savedInstanceState);
 
     setContentView(R.layout.activity_main);
 
     String apkPath = getPackageCodePath();
 
     Long dexCrc = Long.parseLong(getString(R.string.classesdex_crc));
 
     try
 
     {
 
         ZipFile zipfile = new ZipFile(apkPath);
 
         ZipEntry dexentry = zipfile.getEntry( "classes.dex" );
 
         Log.i( "verification" , "classes.dexcrc=" +dexentry.getCrc());
 
         if (dexentry.getCrc() != dexCrc){
 
         Log.i( "verification" , "Dexhas been modified!" );
 
         } else {
 
         Log.i( "verification" , "Dex hasn't been modified!" );
 
         }
 
     } catch (IOException e) {
 
      // TODO Auto-generated catch block
 
      e.printStackTrace();
 
     }
 
    }
 
}




注意:R.string.classesdex_crc的值如今能够是个随机数。 ide

(2)运行程序打印结果,个人apk程序的classes.dex的crc32的值为713769644spa

(3)将上面程序的classes.dex文件的crc32的值,保存在资源文件字符串中classesdex_crc中(固然也能够保存在服务器上,而后经过网络获取校验),而后再运行上面的apk程序,打印以下:.net

Dex hasn't beenmodified! code

(4)这时咱们在上面的代码中随便加一行或者一个空格,而后从新编译运行会看到咱们的程序的crc32的值改变了。程序打印以下:blog

Dex has beenmodified!

3、用哈希值对整个apk完整性进行校验

因为咱们要对整个apk的完整性进行校验,因此咱们的算出哈希值就不能存在资源文件中了由于apk中任何的改动都会引发最终apk生成的哈希值的不一样。

(1)首先实现apk中计算自身哈希值的代码,以下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class MainActivity extendsActivity {
 
@Override
 
protectedvoid onCreate(Bundle savedInstanceState) {
 
      super .onCreate(savedInstanceState);
 
      setContentView(R.layout.activity_main);
 
      String apkPath = getPackageCodePath();
 
      MessageDigest msgDigest = null ;
 
      try {
 
         msgDigest = MessageDigest.getInstance( "SHA-1" );
 
         byte [] bytes = new byte [ 1024 ];
 
         int byteCount;
 
         FileInputStream fis = new FileInputStream( new File(apkPath));
 
         while ((byteCount = fis.read(bytes)) > 0 )
 
         {
 
             msgDigest.update(bytes, 0 , byteCount);
 
         }
 
         BigInteger bi = new BigInteger( 1 , msgDigest.digest());
 
         String sha = bi.toString( 16 );
 
         fis.close();
 
         //这里添加从服务器中获取哈希值而后进行对比校验
 
         } catch (Exception e) {
 
             e.printStackTrace();
 
         }
 
     }
 
}




(2)用linux下的sha1sum命令计算咱们的apk的哈希值,命令以下:

sha1sum verification.apk

(3)将(2)中生成的哈希值存到服务器上,而后在咱们的代码中从服务器获取进行完整性比较。

上面咱们用计算crc32和哈希值的方法分别对classes.dex文件和整个apk完整性进行了校验,固然两个校验方法也能够互换使用。根据上面的讲述相信你们对校验文件完整性的方法有了必定的了解,

相关文章
相关标签/搜索