App安全
经常做的网络参数加密解密,以及防止数据重放之外,还提到了防范反编译的风险,其实Apple算比较安全的了,反编译过来也就看到.h文件....但把代码混淆还是会比较好些。
一、iOS 中的网络加密
但是不论在任何时候,都应该将服务置于HTTPS上,因为它可以避免中间人攻击的问题,还自带了基于非对称密钥的加密通道!使用HTTPS后,可以省去各种加解密技术。
介绍下HTTPS交互原理
简答说,HTTPS 就是 HTTP协议加了一层SSL协议的加密处理,SSL 证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA(如GlobalSign,wosign),在验证服务器身份后颁发,这是需要花钱滴,签发后的证书作为公钥一般放在服务器的根目录下,便于客户端请求返回给客户端,私钥在服务器的内部中心保存,用于解密公钥。
HTTPS 客户端与服务器交互过程:
1、客户端发送请求,服务器返回公钥给客户端;
2、客户端生成对称加密秘钥,用公钥对其进行加密后,返回给服务器;
3、服务器收到后,利用私钥解开得到对称加密秘钥,保存;
4、之后的交互都使用对称加密后的数据进行交互。
谈下证书
简单说,证书有两种,一种是正经的:
一种是不正经的:
介绍下我们需要做什么
如果遇到正经的证书,我们直接用AFNetworking 直接请求就好了,AFNetworking 内部帮我们封装了HTTPS的请求方式,但是大部分公司接口都是不正经的证书,这时需要我们做以下几步:
1、将服务器的公钥证书拖到Xcode中
2、修改验证模式
- manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
原理:
简单来说,就是你本可以修改AFN这个设置来允许客户端接收服务器的任何证书,但是这么做有个问题,就是你无法验证证书是否是你的服务器后端的证书,给中间人攻击,即通过重定向路由来分析伪造你的服务器端打开了大门。
- AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
- securityPolicy.allowInvalidCertificates = YES;
- openssl x509 -in <你的服务器证书>.pem -outform der -out server.cer
然后将生成的server.cer文件,如果有自建ca,再加上ca的cer格式证书,引入到app的bundle里,AFNetworking在
- AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
或者
- AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
情况下,会自动扫描bundle中.cer的文件,并引入,这样就可以通过自签证书来验证服务器唯一性了。
AFSecurityPolicy分三种验证模式:
AFSSLPinningModeNone
这个模式表示不做SSL pinning,
只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书就不会通过。
AFSSLPinningModeCertificate
这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
AFSSLPinningModePublicKey
这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,
只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
除了证书加密:
用 POST 请求提交用户的隐私数据,还是不能完全解决安全问题。因此:我们经常会用到加密技术,比如说在登录的时候,我们会先把密码用MD5加密再传输给服务器 或者 直接对所有的参数进行加密再POST到服务器。
1.数据安全介绍
最基础的是我们发送网络请求时,使用
get
和post
方式发送请求。两者具体区别就不做解释了,只是引出相关安全性问题get
:将参数暴露在外,(绝对不安全-->明文请求或者傻瓜式请求)。post
:将参数放到请求体body中,(相对于get比较安全-->但是我们可以很容易用一些软件截获请求数据。比如说Charles(青花瓷)
)
Charles
(大部分app的数据来源都使用该工具来抓包,并做网络测试)- 注意:Charles在使用中的乱码问题,可以显示包内容,然后打开info.plist文件,找到java目录下面的VMOptions,在后面添加一项:-Dfile.encoding=UTF-8
数据安全的原则
- 在网络上
不允许
传输用户隐私数据的明文
,(即:App网络传输安全,指对数据从客户端传输到Server中间过程的加密,防止网络世界当中其他节点对数据的窃听)。 - 在本地
不允许
保存用户隐私数据的明文
,(即:App数据存储安全,主要指在磁盘做数据持久化的时候所做的加密)。 - App
代码安全
,(即:包括代码混淆,加密或者app加壳)。
- 在网络上
要想非常安全的传输数据,建议使用https。抓包不可以,但是中间人攻击则有可能。建议双向验证防止中间人攻击,可以参考下文篇章。
2、常用加密算法
编码方案 Base64
哈希(散列)函数 MD5(消息摘要算法)
SHA1
SHA256
对称加密算法 DES
AES
非对称加密算法 RSA
HTTPS HTTP+SSL协议
3、常用加密方式
1.通过简单 BASE64编码 防止数据明文传输
2.对普通请求、返回数据,生成MD5校验(MD5中加入动态密钥),进行数据完整性(简单防篡改,安全性较低,优点:快速)校验
3.对于重要数据,使用RSA进行数字签名,起到防篡改作
4.对于比较敏感的数据,如用户信息(登陆、注册等),客户端发送使用RSA加密,服务器返回使用DES(AES)加密
5.要想非常安全的传输数据,建议使用https。抓包不可以,但是中间人攻击则有可能。建议双向验证防止中间人攻击
4.Base64编码方案
Base64简单说明
描述:Base64可以成为密码学的基石,非常重要。
特点:可以将任意的二进制数据进行Base64编码
结果:所有的数据都能被编码为并只用65个字符(A~Z a~z 0~9 + / =)就能表示的文本文件。
注意:对文件进行base64编码后文件数据的变化:编码后的数据~=编码前数据的4/3,会大1/3左右。Base64编码原理和处理过程
- Base64实现代码
- // 对一个字符串进行base64编码,并且返回
- -(NSString *)base64EncodeString:(NSString *)string {
- // 1.先转换为二进制数据
- NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
- // 2.对二进制数据进行base64编码,完成之后返回字符串
- return [data base64EncodedStringWithOptions:0];
- }
- // 对base64编码之后的字符串解码,并且返回
- -(NSString *)base64DecodeString:(NSString *)string {
- // 注意:该字符串是base64编码后的字符串
- // 1.转换为二进制数据(完成了解码的过程)
- NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:0];
- // 2.把二进制数据在转换为字符串
- return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
- }
- //---------------------------<#我是分割线#>------------------------------//
- NSLog(@"%@",[self base64EncodeString:@"A"]);
- NSLog(@"%@",[self base64DecodeString:@"QQ=="]);
PS.终端执行编码和解码
- 如:
- 编码:base64 123.png -o 123.txt
- 解码:base64 123.txt -o test.png -D
4.加密实现代码
哈希(散列)函数
特点:
- 算法是公开的
- 对相同的数据加密,得到的结果是一样的"
- 对不同的数据加密,得到的结果是定长的,MD5对不同的数据进行加密,得到的结果都是 32 个字符长度的字符串
- 信息摘要,信息"指纹",是用来做数据识别的!
- 不能逆推反算(重要)
用途:
- 版权 对文件进行散列判断该文件是否是正版或原版的
- 文件完整性验证 对整个文件进行散列,比较散列值判断文件是否完整或被篡改
- 密码加密,服务器并不需要知道用户真实的密码!
- 搜索:
如:百度搜索-->老司机 皮皮虾 苍老师
或是 【苍老师 老司机 皮皮虾 】
上面两种方式搜索出来的内容是一样的- 如何判断:对搜索的每个关键字进行三列,得到三个相对应的结果,按位相加结果如果是一样的,那搜索的内容就是一样的!
- 经典加密算法:
MD5、SHA1、SHA512
MD5消息摘要算法
简单介绍:
- MD5:全称是Message Digest Algorithm 5,译为“消息摘要算法第5版”(经MD2、MD3和MD4发展而来)
- 效果:对输入信息生成唯一的128位散列值(32个字符),即 32个16进制的数字。
特点:
- 输入两个不同的明文不会得到相同的输出值
- 根据输出值,不能得到原始的明文,即其过程不可逆(只能加密, 不能解密)
应用:
- 现在的MD5已不再是绝对安全(如:暴力破解的网站),对此,可以对MD5稍作改进,以增加解密的难度。
- 解决:加盐(Salt):在明文的固定位置插入随机串,然后再进行MD5(先加密,后乱序:先对明文进行MD5,然后对加密得到的MD5串的字符进行乱序)
注意点:
- 开发中,一定要和后台开发人员约定好,MD5加密的位数是16位还是32位(大多数都是32位的),16位的可以通过32位的转换得到。
- MD5加密区分 大小写,使用时要和后台约定好。
- MD5公认被破解不代表其可逆,而是一段字符串加密后的密文,可以通过强大运算计算出字符串加密后的密文对应的原始字符串,但也不是绝对的被破解。
PS.暴力破解是指通过将明文和生成的密文进行配对,生成强大的数据库,在数据库中搜索,在这里就可以破解密码。破解网址 http://www.cmd5.com
提升MD5加密安全性,解决办法
- 1.先明文加盐,然后再进行MD5。即明文后拼接字符串(此时拼接的字符串要 足够长+足够咸+足够复杂),再进行MD5加密。如:
#define salt @"1342*&%&shlfhs390(*^^6R%@@KFGKF"
2.先加密+乱序
3.乱序|加盐,多次MD5加密等
- 4.使用消息认证机制HMAC:给定一个"秘钥",对明文进行加密,并且做"两次散列"!-> 得到的结果,还是 32 个字符,相对安全(KEY是服务器传给你的,不是你写死的)。
消息认证机制(HMAC)简单说明
- 原理
- 消息的发送者和接收者有一个共享密钥
- 发送者使用共享密钥对消息加密计算得到MAC值(消息认证码)
- 消息接收者使用共享密钥对消息加密计算得到MAC值
- 比较两个MAC值是否一致
- 使用
- 客户端需要在发送的时候把(消息)+(消息·HMAC)一起发送给服务器
- 服务器接收到数据后,对拿到的消息用共享的KEY进行HMAC,比较是否一致,如果一致则信任
简单示例
- #pragma mark - md5加密方法
- - (NSString *)md5String {
- const char *str = self.UTF8String;
- uint8_t buffer[CC_MD5_DIGEST_LENGTH];
- CC_MD5(str, (CC_LONG)strlen(str), buffer);
- return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
- }
- #pragma mark - HMACMD5加密方法
- - (NSString *)hmacMD5StringWithKey:(NSString *)key {
- const char *keyData = key.UTF8String;
- const char *strData = self.UTF8String;
- uint8_t buffer[CC_MD5_DIGEST_LENGTH];
- CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
- return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
- }
- /**
- * 返回二进制 Bytes 流的字符串表示形式
- * @param bytes 二进制 Bytes 数组
- * @param length 数组长度
- * @return 字符串表示形式
- */
- - (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
- NSMutableString *strM = [NSMutableString string];
- for (int i = 0; i < length; i++) {
- [strM appendFormat:@"%02x", bytes[i]];
- }
- return [strM copy];
- }
- //---------------------------<#我是分割线#>------------------------------//
- // md5加密调用
- NSLog(@"%@",[@"520it" md5String]);
- // (明文+加盐)MD5加密调用
- NSLog(@"%@",[[@"520it" stringByAppendingString:salt] md5String]);
- // hmacMD5加密调用(先加密+乱序)
- NSLog(@"%@",[@"520it" hmacMD5StringWithKey:@"xiaomage"]);
对称加密算法AES和DES
- 对称加密的特点
- 加密/解密使用相同的密钥
- 加密和解密的过程是可逆的
- 经典算法
- DES 数据加密标准
- AES 高级加密标准
- 提示:
- 加密过程是先加密,再base64编码
- 解密过程是先base64解码,再解密
简单示例
- /**
- * 加密字符串并返回base64编码字符串
- *
- * @param string 要加密的字符串
- * @param keyString 加密密钥
- * @param iv 初始化向量(8个字节)
- *
- * @return 返回加密后的base64编码字符串
- */
- - (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
- /**
- * 解密字符串
- *
- * @param string 加密并base64编码后的字符串
- * @param keyString 解密密钥
- * @param iv 初始化向量(8个字节)
- *
- * @return 返回解密后的字符串
- */
- - (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
- // 调用
- EncryptionTools *encrypt = [EncryptionTools sharedEncryptionTools];
- NSLog(@"%@",[encrypt encryptString:@"LN123" keyString:@"LN" iv:nil]);
- NSLog(@"%@",[encrypt decryptString:@"OPcTMDB5paivqtYo9Fj+hQ==" keyString:@"LN" iv:nil]);
非对称加密RSA
- 非对称加密的特点
- 使用 公钥 加密,使用 私钥 解密
- 使用 私钥 加密,使用 公钥 解密(私钥签名,公钥验签)
- 公钥是公开的,私钥保密
- 加密处理安全,但是性能极差
- 经典算法-->RSA
简单示例
- // 公钥加密时调用类方法:
- + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
- + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;
- // 私钥解密时调用类方法
- + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
- + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privacy;
- /** 调用 */
- NSString *str = [RSAUtil encryptString: @"LN" publicKey:RSA_Public_key];
- NSLog(@"RSA公钥加密数据-->\n%@",str);
- NSString *str1 = [RSAUtil decryptString:str privateKey:RSA_Privite_key];
- NSLog(@"RSA私钥解密数据-->%@",str1);
MAC上生成公钥、私钥的方法,及使用
- # MAC上生成公钥、私钥的方法
- @code
- 1.打开终端,切换到自己想输出的文件夹下
- 2.输入指令:openssl(openssl是生成各种秘钥的工具,mac已经嵌入)
- 3.输入指令:genrsa -out rsa_private_key.pem 1024 (生成私钥,java端使用的)
- 4.输入指令:rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout (生成公钥)
- 5.输入指令:pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt(私钥转格式,在ios端使用私钥解密时用这个私钥)
- 注意:在MAC上生成三个.pem格式的文件,一个公钥,两个私钥,都可以在终端通过指令vim xxx.pem 打开,里面是字符串,第三步生成的私钥是java端用来解密数据的,第五步转换格式的私钥iOS端可以用来调试公钥、私钥解密(因为私钥不留在客户端)
- iOS端公钥加密私钥解密、java端公钥加密私钥解密,java端私钥加密公钥解密都容易做到,iOS不能私钥加密公钥解密,只能用于验签
- @endcode
5.HTTPS基本使用
https简单说明
- HTTPS(
全称:Hyper Text Transfer Protocol over Secure Socket Layer
),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。 - 在HTTP下加入
SSL层
,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。 - HTTPS:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。
- HTTPS(
注意
- HTTPS的主要思想是在不安全的网络上创建一安全信道,并可在使用适当的加密包和服务器证书可被验证且可被信任时,对窃听和中间人攻击提供合理的保护。
- HTTPS的信任继承基于预先安装在浏览器中的证书颁发机构(如VeriSign、Microsoft等)(意即“我信任证书颁发机构告诉我应该信任的”)。
- 因此,一个到某网站的HTTPS连接可被信任,如果服务器搭建自己的https 也就是说采用自认证的方式来建立https信道,这样一般在客户端是不被信任的。
- 所以我们一般在浏览器访问一些https站点的时候会有一个提示,问你是否继续。
HTTPS和HTTP区别
- https协议需要到
ca申请证书
,一般免费证书很少,需要交费。 - http是超文本传输协议,信息是明文传输,https 则是具有安全性的
ssl加密传输协议
。 - http和https使用的是完全不同的连接方式,用的端口也不一样,
前者是80
,后者是443
。 - http的连接很简单,是无状态的;HTTPS协议是由
SSL+HTTP协议
构建的可进行加密传输、身份认证的网络协议,比http协议安全。
- https协议需要到
实现代码
方案一:如果是自己使用NSURLSession来封装网络请求
- // 1.创建session
- NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
- // 2.创建Task
- NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://kyfw.12306.cn/otn"]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- // 3.解析数据
- NSLog(@"%@---%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
- }];
- // 4.执行task
- [dataTask resume];
- #pragma mark - 遵守<NSURLSessionDataDelegate>
- // 如果发送的请求是https的,那么才会调用该方法
- -(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
- /**
- 判断服务器传给我们的信任的类型,只有是【服务器信任的时候,才安装证书】
- NSURLSessionAuthChallengeDisposition 如何处理证书
- NSURLAuthenticationMethodServerTrust 服务器信任
- */
- if(![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
- return;
- }
- NSLog(@"%@",challenge.protectionSpace);
- /*
- NSURLCredential 授权信息
- NSURLSessionAuthChallengeUseCredential = 0, 使用该证书 安装该证书
- NSURLSessionAuthChallengePerformDefaultHandling = 1, 默认采用的方式,该证书被忽略
- NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 取消请求,证书忽略
- NSURLSessionAuthChallengeRejectProtectionSpace = 3, 拒绝
- */
- NSURLCredential *credential = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
- completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
- // 注意:并不是所有的https的请求都需要安装证书(授权)的,请求一些大型的网站有的是强制安装的,如:苹果官网https://www.apple.com
- }
方案二:如果使用AFN网络请求
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- // 更改解析方式(请求网页源码应使用原始解析)
- manager.responseSerializer = [AFHTTPResponseSerializer serializer];
- // 设置对证书的处理方式
- // 允许自签名证书,必须的
- manager.securityPolicy.allowInvalidCertificates = YES;
- // 是否验证域名的CN字段(不是必须的,但是如果写YES,则必须导入证书)
- manager.securityPolicy.validatesDomainName = NO;
- [manager GET:@"https://kyfw.12306.cn/otn" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSLog(@"success---%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]);
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- NSLog(@"error---%@",error);
- }];
6.数据安全--加密解密效果
二、如何有效防止API的重放攻击
API重放攻击(Replay Attacks)又称重播攻击、回放攻击,这种攻击会不断恶意或欺诈性地重复一个有效的API请求。攻击者利用网络监听或者其他方式盗取API请求,进行一定的处理后,再把它重新发给认证服务器,是黑客常用的攻击方式之一。
HTTPS数据加密是否可以防止重放攻击?
否,加密可以有效防止明文数据被监听,但是却防止不了重放攻击。
一般使用以时间戳作为传参,后台协商响应时间差范围,参考三次握手协议两边商量序列号,当发过来的序列号为服务器也存在的序列号则丢弃。
使用签名防止重放攻击
使用签名之后,可以对请求的身份进行验证。但不同阻止重放攻击,即攻击者截获请求后,不对请求进行任何调整。直接使用截获的内容重新高频率发送请求。
API网关提供了一套有效防止重放攻击的方法。开启API网关的重放,需要您使用“阿里云APP”的认证方式。通过这种签名认证方式,每个请求只能被使用一次,从而防止重放。
阿里云APP:是基于请求内容计算的数字签名,用于API网关识别用户身份。客户端调用API时,需要在请求中添加计算的签名。API网关在收到请求后会使用同样的方法计算签名,同用户计算的签名进行比较,相同则验证通过,不同则认证失败。这种认证的签名方式请参照:请求签名
在API网关的签名中,提供X-Ca-Timestamp、X-Ca-Nonce两个可选HEADER,客户端调用API时一起使用这两个参数,可以达到防止重放攻击的目的。
原理
- 请求所有的内容都被加入签名计算,所以请求的任何修改,都会造成签名失败。
不修改内容
X-Ca-Timestamp:发起请求的时间,可以取自机器的本地实现。当API网关收到请求时,会校验这个参数的有效性,误差不超过15分钟。
X-Ca-Nonce:这个是请求的唯一标识,一般使用UUID来标识。API网关收到这个参数后会校验这个参数的有效性,同样的值,15分内只能被使用一次。
三、代码混淆
一、在项目根目录下新建confuse.sh 和 gbFunc.list 文件
说明:
confuse.sh 文件在编译过程中会执行gbFunc.list 用于自动混淆代码时,存放过滤出来需要混淆的方法名
touch confuse.sh
touch gbFunc.list
二、新建GBConfuse.h
说明:
GBConfuse.h 是在自动混淆代码时,将会把自动生成的字符串定义成宏,存放在此文件,也便于查看。
注意:需要把.h文件移到项目文件外,因为放项目文件中,到时被反编译过来,还是能得到GBConfuse.h里面的东西的,就能通过比对,得到方法。(后面用class-dump反编译过来就明白了...)
在confuse.sh中添加如下代码
- #!/usr/bin/env bash
- TABLENAME=symbols
- SYMBOL_DB_FILE="symbols"
- #func.list路径
- STRING_SYMBOL_FILE="$PROJECT_DIR/GBFunc.list"
- #项目文件路径
- CONFUSE_FILE="$PROJECT_DIR/Safedemo"
- #Confuse.h路径
- HEAD_FILE="$PROJECT_DIR/GBConfuse.h"
- export LC_CTYPE=C
- #取以.m或.h结尾的文件以+号或-号开头的行 |去掉所有+号或-号|用空格代替符号|n个空格跟着<号 替换成 <号|开头不能是IBAction|用空格split字串取第二部分|排序|去重复|删除空行|删掉以init开头的行>写进func.list
- grep -h -r -I "^[-+]" $CONFUSE_FILE --include '*.[mh]' |sed "s/[+-]//g"|sed "s/[();,: *^/{]/ /g"|sed "s/[ ]*</</"| sed "/^[ ]*IBAction/d"|awk '{split($0,b," "); print b[2]; }'| sort|uniq |sed "/^$/d"|sed -n "/^GBSAFE_/p" >$STRING_SYMBOL_FILE
- #维护数据库方便日后作排重,以下代码来自念茜的微博
- createTable()
- {
- echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
- }
- insertValue()
- {
- echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
- }
- query()
- {
- echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
- }
- ramdomString()
- {
- openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
- }
- rm -f $SYMBOL_DB_FILE
- rm -f $HEAD_FILE
- createTable
- touch $HEAD_FILE
- #这里也要做修改
- echo '#ifndef GBConfuse_h
- #define CodeConfuse' >> $HEAD_FILE
- echo "//confuse string at `date`" >> $HEAD_FILE
- cat "$STRING_SYMBOL_FILE" | while read -ra line; do
- if [[ ! -z "$line" ]]; then
- ramdom=`ramdomString`
- echo $line $ramdom
- insertValue $line $ramdom
- echo "#define $line $ramdom" >> $HEAD_FILE
- fi
- done
- echo "#endif" >> $HEAD_FILE
- sqlite3 $SYMBOL_DB_FILE .dump
需要修改的代码在于文件路径:
添加 Run Script
添加 PCH 文件
在ViewController中添加以"GBSAFE_"为前缀的测试方法
测试
运行报错如下:
原因是.sh文件没有权限,所以需要去开启权限。
在confuse.sh文件目录下,执行命令:
- chmod 755 confuse.sh
运行成功!
先打包一个.ipa安装包进行测试!
先不进行代码混淆:
把.ipa文件类型改成.zip,解压得到.app文件
新建Hear文件夹用于保存反编译后得到的文件:
用class-dump进行反编译
- class-dump -H 要破解的可执行文件路径 -o 破解后的头文件存放路径
得到没有进行代码混淆的文件:
可以看到都是项目中一些.h文件,打开可以看到完整的方法名....
然后客户说测试公司说不安全...
需要进行代码混淆...
在PCH文件中,引用GBConfuse.h:
重新打包..就可以得到混淆后的.ipa..
下面就是混淆后的结果。
总结:
其实,原理应该就是在编译过程中,把需要混淆的代码生成随机字符串进行替换....
App安全的更多相关文章
- App开发:模拟服务器数据接口 - MockApi
为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...
- Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记
以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- SQLSERVER走起 APP隆重推出
SQLSERVER走起 APP隆重推出 为方便大家查看本微信公众以前推送的文章,QQ群里面的某位SQLSERVER重度爱好者开发了<SQLSERVER走起>的APP 以供大家一起交流 网页 ...
- 从中间件的历史来看移动App开发的未来
在移动开发领域我们发现一个很奇怪的现象:普通菜鸟新手经过3个月的培训就可以拿到 8K 甚至上万的工作:在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资.不知道大家是否想过:移动应用开 ...
- 搞个这样的APP要多久?
这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正对面坐着来访的王总,他是在别处打拼的人,这几年据说收获颇丰,见移动互联网如火如荼,自然也想着要 ...
- app开发外包注意事项,2017最新资讯
我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...
- 【Win 10 应用开发】在App所在的进程中执行后台任务
在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后 ...
- 猖獗的假新闻:2017年1月1日起iOS的APP必须使用HTTPS
一.假新闻如此猖獗 刚才一位老同事 打电话问:我们公司还是用的HTTP,马上就到2017年了,提交AppStore会被拒绝,怎么办? 公司里已经有很多人问过这个问题,回答一下: HTTP还是可以正常提 ...
随机推荐
- Python并发复习1 - 多线程
一.基本概念 程序: 指令集,静态, 进程: 当程序运行时,会创建进程,是操作系统资源分配的基本单位 线程: 进程的基本执行单元,每个进程至少包含一个线程,是任务调度和执行的基本单位 > 进程和 ...
- CSS3-flex弹性布局之flex属性
flex属性 前置
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-6 直接光源采样
Chapter7 Sample Lights Directly Preface 今天我们来讲这个还算牛逼的技术——直接光源采样 之前我们提到过,在2-7 前两篇我们也提到要减少噪点,就是图片上的黑点 ...
- basename
我使用过的Linux命令之basename - 去掉文件名的目录和后缀 本文链接:http://codingstandards.iteye.com/blog/840784 (转载请注明出处) 用途 ...
- asp.net core Session的测试使用心得及注意事项
sp.net-core中Session是以中间件的形式注册使用的.不比asp.net中的使用,直接使用Session就行. 首先在.net-core框架中注入Session中间件,首先在Configu ...
- webpack打包之有依赖js模块
一.入口文件main.js var isd = require('./depend.js'); if(isd.isDepend){ console.log('有依赖模块'); } else { con ...
- 原生JavaScript支持6种方式获取元素
一.原生JavaScript支持6种方式获取元素 document.getElementById('id'); document.getElementsByName('name'); document ...
- BZOJ2240 : ural1676 Mortal Combat
首先如果最大匹配不足$n$个那么显然每条边都不可能在匹配为$n$的方案中. 对于一条边$(u,v)$,如果它可能在最大匹配中,有两种情况: $1.(u,v)$是当前方案的匹配边. $2.$可以沿着$( ...
- python网络编程(六)
tcp通信模型 tcp服务器 在程序中,如果想要完成一个tcp服务器的功能,需要的流程如下: socket创建一个套接字 bind绑定ip和port listen使套接字变为可以被动链接 accept ...
- Python核心编程(第二版)正则表达式练习题解
15-1. 识别下列字符串:“bat,” “bit,” “but,” “hat,” “hit,” 或 “hut” from re import match word = raw_input('inpu ...