防护IOS APP安全的几种方式(详解)

2018-09-27 10:23:18 浏览数 (1)

1.URL编码加密 对iOS app中出现的URL进行编码加密,防止URL被静态分析 2.本地数据加密 对NSUserDefaults,sqlite存储文件数据加密,保护iOS app的帐号和关键信息。 3.网络传输数据加密 对iOS app客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取 4.方法体,方法名高级混淆 对iOS app的方法名和方法体进行混淆,保证源码被逆向后无法解析代码 5.程序结构混排加密 对iOS app逻辑结构进行打乱混排,保证源码可读性降到最低

一 .URL编码加密

1.背景介绍 a. iOS 下URL加解密,项目使用AFNetworking. b. 虽然是使用HTTPS,但是从安全方面考虑,在很多情况下还是需要对url的参数进行加密的. c. 不管是get请求还是post请求,都可以对后边的参数进行加密,这里说下post请求。

2.加密方式 a. 加密:首先对字符串记性AES128加密,然后进行base64加密(主要是为了去除特殊字符) b. 其中base64加解密使用 GTMBase64添加两个方法 c. 解密:先base64解密,然后在AES128解密即可还原数据

3.加密代码

代码语言:javascript复制
加密之前的代码 :
NSMutableDictionary *para = [NSMutableDictionary dictionary];
para[@"method"] = @"encryp";
para[@"userId"] = 35617236572;
para[@"userName"] = @"小红";
para[@"code"] = @"1521***6657";
 NSString *url = [NSString stringWithFormat:@"%@ActivityAction/saveActivity.do", serverURL];
AFHTTPRequestOperation *operation = [NetWorkInst POST:url parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {       
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
}];
代码语言:javascript复制
加密之后:
NSMutableDictionary *para = [NSMutableDictionary dictionary];
para[@"method"] = @"encryp";
para[@"userId"] = 35617236572;
para[@"userName"] = @"小红";
para[@"code"] = @"1521***6657";
// 开始加密,格式化数据****************************
NSString *str = [NSString stringWithFormat:@"'method':'encryp','userId':'35617236572 35617236572','userPsw':'小红','content':''1521***6657"];
NSLog(@"原始数据:%@",str);
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSData *aaa = [data AES128EncryptWithKey:@"dt8888"]; // aes加密
NSLog(@"加密AES128后:%@",aaa);
NSString *bbb = [PublicMethod encodeBase64Data:aaa];//base64加密
NSLog(@"base64加密后:%@",bbb);

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"info"] = bbb;

NSString *url = [NSString stringWithFormat:@"https://%@:82/frame/webInteface.do?", NHBaseURL];
AFHTTPRequestOperation *operation = [NetWorkInst POST:url parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {       
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
}];

其中URLString可以作为最基础的,不需要加密 parameters 就是我们需要加密的地方,这是一个字典,因为AFN会对这个parameters进行解析,所以对这个参数集合进行一次包装,拼接成一个字符串。然后对字符串进行加密。

base64加解密使用 GTMBase64添加两个方发如下:

代码语言:javascript复制
//加密
  (NSString*)encodeBase64Data:(NSData *)data {
    data = [GTMBase64 encodeData:data];
    NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return base64String;
}
//解密
  (NSData*)decodeBase64String:(NSString * )input {
    NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    data = [GTMBase64 decodeData:data];
    return data;
}

AES128使用系统CommonCrypto/CommonCryptor.h实现 //用于AES 添加NSData分类,增加两个方法

代码语言:javascript复制
//加密
- (NSData *)AES128EncryptWithKey:(NSString *)key {
    
    char keyPtr[kCCKeySizeAES128   1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    size_t bufferSize = dataLength   kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes],
                                          dataLength, /* input */
                                          buffer,
                                          bufferSize, /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}
//解密
- (NSData *)AES128DecryptWithKey:(NSString *)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128 1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
    
    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    
    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength   kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes],
                                          dataLength, /* input */
                                          buffer,
                                          bufferSize, /* output */
                                          &numBytesDecrypted);
    
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer); //free the buffer;
    return nil;
}

0 人点赞