一个项目中的明文字符串不可胜数,可是有一些是程序的敏感信息的话若是不进行加密和混淆处理,反编译者就会很容易找到咱们的敏感信息。拿到这些敏感信息以后就很容易分析咱们的程序,业务逻辑进而作一些可能对咱们不是很友好的事情,因此一些敏感明文字符串仍是有必要作一下加密,让敏感信息更加安全。特别是对于一些金融类的APP
。ios
这里介绍几个经常使用的:git
class-dump
主要用来反编译一个库文件或者app
的方法名、属性等声明(即.h
文件,强大的是反编译出来的.h
不只仅包含头文件中的声明,.m
中的function
方法名称也一样可以反编译出来)。github
IDA
主要用来反编译库文件的实现(固然方法声明一样可以反编译出来,用class-dump
主要是更加形象,有针对性),这个反编译工具很是强大可以将函数的实现及逻辑关系、流程通通显示出来,弊端就是反编译出来的内容为汇编语言,须要必定汇编基础的才能看懂。看起来比较头疼。shell
Hopper Disassembler
与IDA
功能类似,主要功能都是反编译查看方法的实现,这个软件的功能相对于IDA
来讲,可读性要强不少,反编译出来的内容相似于汇编与OC
的运行时的结合体,相对比较容易看出方法的具体实现。本次也是采用此工具进行验证。sass
在探索明文字符串加密以前先来了解一下代码混淆:安全
shell
脚本Warning!!! 前方高能bash
Guideline 2.3.1 - Performance We discovered that your app contains hidden features. Specifically, It would be appropriate to remove all code obfuscation and selector mangling or to explain in detail the purpose of its inclusion before resubmitting for review.app
听说从17年开始苹果拒审代码混淆的APP
。因此项目总体代码的混淆目前感受意义不大。ide
第三方的服务(例如:网易云易盾)这类的加固成效如何不太清楚,这里拿出来给个参考,毕竟没用过,多是否选用要看公司的决策了。函数
第三方明确说明了加固中使用了代码混淆,不知道是使用什么黑科技混淆的,确定不是跑脚本的方式,好奇宝宝能够研究一下~~
对于被砸壳的二进制文件,逆向分析人员分析代码有一条重要线索,也就是被硬编码的明文字符串。好比说,你的app
被人抓包了,某些数据请求接口也被人发现了,那么很简单,逆向人员能够直接拷贝特征比较明显的字符串到hopper
中搜索,经过查看该字符串被引用的地方,能够很快的找到相应的逻辑代码。对于这一步的防范,须要作的就是对硬编码的明文进行加密。
inline
函数避免了普通函数的,在汇编时必须调用call
的缺点。定义:
UIKIT_STATIC_INLINE NSString *testScheme() {
return @"testtesttesttest";
}
static inline NSString * testName() {
return @"test";
}
复制代码
使用:
@"appId": testRrd(),
@"scheme" : testScheme()
复制代码
结果:
很明显明文字符串仍是很容易暴露出来~~,方案被PASS!
Swift
的支持也不是很即时。Swift
的二进制文件(例如:class-dump
)。Swift
的工具也表现出Swift
更安全的一面。我对一样逻辑的一样代码(只是语法不一样)的OC
和Swift
方法(方法中包含明文字符串)进行了测试:
上面对比明显能够看出OC
通过反编译以后暴露出来的信息更能多,而且明文字符串显而易见。可是若是Swift
方法添加了对OC
的支持(@objc
)也会使安全性下降。
目前来看纯Swift
代码确实比纯OC
或者混编的代码更安全一些。
有个开源代码能够用,UAObfuscatedString,这个开源混淆代码写出来的字符串是以点语法的方式链接起来。
语法:
@"url" : NSMutableString.string.w.w.w.dot.b.a.i.d.u.dot.c.o.m
复制代码
测试混淆结果:
UAObfuscatedString 是经过Category
和Extension
来实现这种点语法拼接字符串,存在比较明显的规律,外加它是开源的可能安全性不是很高,如单从加密的角度去使用这个开源库感受意义不大。
原理:经过位运算的^
异或运算符把字符串与一个指定的值进行运算,从而改变字符串中每一个字符的值,这样就能够获得一个加密后的字符串;当把加密后的字符串做为程序输入内容后,异或运算会把加密后的字符串还原为原有字符串的值。
使用:
@"key" : testMethod()
复制代码
// Key 能够是0~255的Int
#define XORKEY 0xC9
static void XOREncrypt(unsigned char *str, unsigned char key) {
unsigned char *p = str;
while (((*p) ^= key) != '\0') {
p++;
}
}
static id testMethod(void) {
unsigned char str[] = {(XORKEY ^ 'e'), (XORKEY ^ 'n'), (XORKEY ^ 'c'), (XORKEY ^ 'r'),
(XORKEY ^ 'y'), (XORKEY ^ 'p'), (XORKEY ^ 't'), (XORKEY ^ '\0')};
XOREncrypt(str, XORKEY);
static unsigned char result[7];
memcpy(result, str, 7);
return [[NSString alloc] initWithFormat:@"%s", result];
}
复制代码
这里将字符用函数指针成员的形式存储,反编译后,只留下了地址,去掉了明文字符串直接暴露的风险。