博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android apk 防止反编译技术第五篇-完整性校验(转)
阅读量:6912 次
发布时间:2019-06-27

本文共 2670 字,大约阅读时间需要 8 分钟。

hot3.png

一、完整性校验原理

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

二、用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的值现在可以是个随机数。

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

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

Dex hasn't beenmodified!

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

Dex has beenmodified!

三、用哈希值对整个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完整性进行了校验,当然两个校验方法也可以互换使用。根据上面的讲述相信大家对校验文件完整性的方法有了一定的了解,

转载于:https://my.oschina.net/jesonzhang/blog/419860

你可能感兴趣的文章
系统调优之二CPU子系统
查看>>
Windows Server 2012 NIC功能
查看>>
Goldengate双向复制配置
查看>>
sshd 已死 但是subsys被锁或者Sshd dead but subsys locked
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
在主引导记录(MBR)的救援模式下如何重新安装GRUB引导装载程序
查看>>
我的友情链接
查看>>
git的基本使用和示例
查看>>
用户管理
查看>>
从输入 URL 到页面加载完的过程中都发生了什么事情?
查看>>
揭秘Windows Server2012 核心虚拟化技术Hyper-V
查看>>
java参数传递(值传递还是引用传递)
查看>>
去除文本中重复的行方法
查看>>
On Stack Replacement and JIT
查看>>
CDN业务检测(蓝汛/帝联)
查看>>
Storm数据流模型的分析及讨论
查看>>
VR风暴将至虚拟现实的中国故事该怎么写?
查看>>
java多线程
查看>>
jvisualvm 远程监控Linux下的tomcat
查看>>