IOSアプリのセキュリティを保護するいくつかの方法(詳細)

6407 ワード

1.URL符号化暗号化iOSアプリに登場するURLを符号化暗号化し、URLが静解析されることを防止する.ローカルデータ暗号化NSUserDefaults、sqliteストレージファイルデータ暗号化、iOS appのアカウントとキー情報を保護します.3.ネットワーク伝送データの暗号化iOSアプリクライアントの伝送データに対して暗号化方案を提供し、効果的にネットワークインタフェースのブロックを通じて4.方法体、方法名の高度な混同iOS appの方法名と方法体を混同し、ソースコードが逆方向に解析できないことを保証する.プログラム構造混在暗号化iOS app論理構造を乱し混在させ、ソースコードの可読性を最小限に抑える

一.URLコード暗号化


1.背景紹介a.iOSのURLを解読し、プロジェクトはAFNetworkingを使用する.b.HTTPSを用いるが、セキュリティ面からurlのパラメータを暗号化する必要がある場合が多い.c.getリクエストでもpostリクエストでも、後のパラメータを暗号化できます.ここでpostリクエストと言います.
2.暗号化方式a.暗号化:文字列記憶性AES 128をまず暗号化してからbase 64を暗号化する(主に特殊文字を除去するため)b.base 64を復号化するGTMBase 64を用いて2つの方法を追加するc.復号化:base 64を復号化してからAES 128を復号化すればデータを復元できる
3.暗号化コード
  :
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 formData) {       
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
}];
 :
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 formData) {       
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
}];

その中でURLStringは最も基礎とすることができて、parametersを暗号化する必要がないのは私たちが暗号化する必要がある場所で、これは辞書で、AFNはこのparametersに対して解析を行うため、このパラメータの集合に対して1回の包装を行って、1つの文字列につなぎ合わせます.文字列を暗号化します.
base 64復号化GTMBase 64を使用して、次の2つの方程式を追加します.
// 
+ (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;
}

AES 128はシステムCommonCrypto/CommonCryptorを使用する.h実装//AESにNSData分類を追加し、2つの方法を追加
// 
- (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;
}