前言:ipa安全检测过程中发现,能检测到ipa中存储在沙盒里面的cookie信息,以及登录用户的敏感信息,这个就涉及到用户隐私安全问题了,针对以上问题我们采取了存储数据的加密的方法解决。
加密方法:字符串进行AES加密
NSData *EncipherData_AES(NSData *indata,CCOperation otype)
{
NSData *retData = nil;
//测试的密钥或向量
Byte tkey[32] = {0};
for (int i = 0; i < 32; i++) {
tkey[i] = 8;
}
Byte iv[16] = {0};
for (int i =0; i < 16; i++) {
iv[i] = 1;
}
CCCryptorRef cryptor = NULL;
CCCryptorStatus ccret;
//创建加密解密器
if (otype==kCCEncrypt) {
ccret = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor);
}
else if (otype == kCCDecrypt)
{
ccret = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor);
}
if (ccret!=kCCSuccess) {
return nil;
}
size_t bufsize = 0;
size_t moved = 0;
size_t total = 0;
//获取最大长度
bufsize = CCCryptorGetOutputLength(cryptor, indata.length, true);
char * buf = (char*)malloc(bufsize);
bzero(buf, bufsize);
//加解密
ccret = CCCryptorUpdate(cryptor,
indata.bytes,indata.length,
buf, bufsize, &moved);
total += moved;
if (ccret!=kCCSuccess) {
return nil;
}
//处理最后的数据块
ccret = CCCryptorFinal(cryptor,
buf+total,
bufsize-total, &moved);
if (ccret!=kCCSuccess) {
return nil;
}
total +=moved;
CCCryptorRelease(cryptor);
retData = [NSData dataWithBytes:buf length:total];
free(buf);
return retData;
}
NSData *EncipherData_AES(NSData *indata,CCOperation otype)
{
NSData *retData = nil;
//测试的密钥或向量
Byte tkey[32] = {0};
for (int i = 0; i < 32; i++) {
tkey[i] = 8;
}
Byte iv[16] = {0};
for (int i =0; i < 16; i++) {
iv[i] = 1;
}
CCCryptorRef cryptor = NULL;
CCCryptorStatus ccret;
//创建加密解密器
if (otype==kCCEncrypt) {
ccret = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor);
}
else if (otype == kCCDecrypt)
{
ccret = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, tkey, kCCKeySizeAES256, iv, &cryptor);
}
if (ccret!=kCCSuccess) {
return nil;
}
size_t bufsize = 0;
size_t moved = 0;
size_t total = 0;
//获取最大长度
bufsize = CCCryptorGetOutputLength(cryptor, indata.length, true);
char * buf = (char*)malloc(bufsize);
bzero(buf, bufsize);
//加解密
ccret = CCCryptorUpdate(cryptor,
indata.bytes,indata.length,
buf, bufsize, &moved);
total += moved;
if (ccret!=kCCSuccess) {
return nil;
}
//处理最后的数据块
ccret = CCCryptorFinal(cryptor,
buf+total,
bufsize-total, &moved);
if (ccret!=kCCSuccess) {
return nil;
}
total +=moved;
CCCryptorRelease(cryptor);
retData = [NSData dataWithBytes:buf length:total];
free(buf);
return retData;
}
NSData *aes_cbc_256(NSData *inData,NSData *key,CCOperation coType)
{
NSData *retData = nil;
if (!inData || !key) {
return nil;
}
if (key.length!=32) {
return nil;
}
NSUInteger dataLength = [inData length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus;
//ecb 模式不需要使用 iv,cbc模式需要,当cbc模式时,如果不传iv,则默任全0
Byte iv[16] = {0};
for (int i = 0; i < 16; i++) {
iv[i] = 1;
}
//加密
if (coType==kCCEncrypt) {
cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,//使用AES算法
kCCOptionPKCS7Padding,
key.bytes, kCCKeySizeAES256,
iv,
[inData bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
}
//解密
else if(coType ==kCCDecrypt)
{
cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
key.bytes, kCCKeySizeAES256,
iv,
[inData bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
}
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return retData;
}
#pragma mark - # 加密字符串
+ (NSData*)addEncipherDataWithString:(NSString*)string{
NSData *srcData = [string dataUsingEncoding:NSASCIIStringEncoding];
NSData *encData = EncipherData_AES(srcData, kCCEncrypt);
return encData;
}
#pragma mark - # 解密
+ (NSString*)decryptEncipherDataWithData:(NSData*)encData{
NSData *decData = EncipherData_AES(encData, kCCDecrypt);
NSString *string = [[NSString alloc] initWithData:decData encoding:NSASCIIStringEncoding];
return string;
}
这个代码里面2种加密方法,你可以选择AES加密,或者aes_cbc_256方案。
使用方法也很简单:
#define UD_(key) [[NSUserDefaults standardUserDefaults] objectForKey:key]
#define setUD_(key,value) [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]
存储数据:
setUD_(USERNAME, [WSEncipherDataManager addEncipherDataWithString:@"test"]);
取数据:
NSString *userName = [WSEncipherDataManager decryptEncipherDataWithData:UD_(USERNAME)];
这样再去检测ipa的话,再看到的数据就是加密之后的二进制数据,保护了用户的隐私信息。