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.加密代碼
加密之前的代碼 :
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) {
}];
加密之後:
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添加兩個方發如下:
//加密
+ (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分類,增加兩個方法
//加密
- (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;
}