//这是需要加密的字典,里面存储这需要上传的参数
NSMutableDictionary *bodyDict=[[NSMutableDictionary alloc] init];
[bodyDict setValue:@"80088202220" forKey:@"phone"];
//这是需要配置的key,需要前后端统一配置
#define StrApiKey @"ios-to-panda"
#define StrSecretKey @"Z4Q5eE}{9Wk8h-P]j3D~$IH8Qo)~)L,c"
#define EncryptKey @"UfbFJ?}2G=WlAu}z`ilz'_^Tf8(&3(yg"
1,接口加密首先需要加时间戳
bodyDict = [self signature:bodyDict strApiKey:StrApiKeystrSecretKey:StrSecretKey];
//数字签名
-(NSMutableDictionary*)signature:(NSMutableDictionary*)bodyDict strApiKey:(NSString*)strApiKey strSecretKey:(NSString*)strSecretKey{
//时间戳
NSString*time = [NSStringstringWithFormat:@"%ld",[selfgetTimeSp]];
[bodyDictsetObject:[NSStringgenmd5:time]forKey:@"nonce"];
[bodyDictsetObject:timeforKey:@"time_stamp"];
//升序排序
NSArray*keyArray = [bodyDictallKeys];
// 利用block进行排序
NSArray*sortkeyArray = [keyArraysortedArrayUsingComparator:^NSComparisonResult(id _Nonnullobj1,id _Nonnullobj2) {
NSComparisonResultresult = [obj1compare:obj2];
returnresult;
}];
inti=0;
NSString*strBaseString =@"";
//生成Base String
for(NSString* paraminsortkeyArray) {
NSString*key;
if([UserShareMgrisUserString:paramCompare:@"city_name"]) {//如果其中有中文需要转码
key = [[DataRequestshareInstance]urlEncode:[bodyDictobjectForKey:[NSStringstringWithFormat:@"%@",param]]];
}else{
key = [bodyDictobjectForKey:[NSStringstringWithFormat:@"%@",param]];
}
if(0==i) {
strBaseString = [NSStringstringWithFormat:@"%@=%@",param,key];
i++;
}else{
strBaseString = [NSStringstringWithFormat:@"%@&%@=%@",strBaseString,param,key];
}
}
//生成签名
NSString*sign = [selfhmacSha1:strBaseString :strSecretKey];
[bodyDictsetObject:signforKey:@"sign"];
returnbodyDict;
}
//hmacsga1加密
- (NSString*)hmacSha1:(NSString*)public_key :(NSString*)private_key{
NSData* secretData = [private_key dataUsingEncoding:NSUTF8StringEncoding];
NSData* stringData = [public_key dataUsingEncoding:NSUTF8StringEncoding];
constvoid* keyBytes = [secretDatabytes];
constvoid* dataBytes = [stringDatabytes];
///#define CC_SHA1_DIGEST_LENGTH 20 /* digest length in bytes */
void* outs = malloc(CC_SHA1_DIGEST_LENGTH);
CCHmac(kCCHmacAlgSHA1, keyBytes, [secretDatalength], dataBytes, [stringDatalength], outs);
// Soluion 1
NSData* signatureData = [NSData dataWithBytesNoCopy:outs length:CC_SHA1_DIGEST_LENGTH freeWhenDone:YES];
NSString *body = [signatureData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
returnbody;
}
//获得当前时间戳
-(long)getTimeSp{
longtime;
NSDate*fromdate=[NSDatedate];
time=(long)[fromdatetimeIntervalSince1970];
returntime;
}
//md5加密方法,直接引用三方库的更好
+ (NSString*)genmd5:(NSString*)str
{
constchar*cStr = [strUTF8String];
unsignedcharresult[16];
CC_MD5( cStr,strlen(cStr), result );
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]];
}
2,进行ase256加密
//将数字签名后的字典转换成data
NSError*parseError =nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyDict options:NSJSONWritingPrettyPrinted error:&parseError];
//将data转成字符串
NSString *bodyString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
//将字符串转成data,至于这里为什么转2次,是因为不转码的话 php解析不了
NSData *dataTake = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
//进行ase256加密
dataTake = [self AES256Encrypt:dataTake WithKey:EncryptKey];
//将data转换成字符串
NSString *body = [dataTake base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//AES256加密
- (NSData*)AES256Encrypt:(NSData*)Data WithKey:(NSString*)key //加密
{
CCCryptorRefcryptor =NULL;
CCCryptorStatusstatus =kCCSuccess;
idiv =nil;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv ==nil|| [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData* keyData, * ivData;
keyData = [(NSMutableData *)[self SHA256Hash:[key dataUsingEncoding:NSUTF8StringEncoding]] mutableCopy];
if( [ivisKindOfClass: [NSStringclass]] )
ivData = [[ivdataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData*) [ivmutableCopy]; // data or nil
// ensure correct lengths for key and iv data, based on algorithms
NSUIntegerkeyLength = [keyDatalength];
if( keyLength <16){
[keyDatasetLength:16];
}elseif( keyLength <24){
[keyDatasetLength:24];
}else{
[keyDatasetLength:32];
}
[ivDatasetLength: [keyDatalength]];
status =CCCryptorCreate( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
[keyDatabytes], [keyDatalength], [ivDatabytes],
&cryptor );
if( status ==kCCSuccess)
{
NSData* result = [self_runData:(NSData*)DataCryptor: cryptorresult: &status];
CCCryptorRelease( cryptor );
returnresult;
}
return nil;
}
- (NSData*) SHA256Hash:(NSData*)data
{
unsigned char hash[CC_SHA256_DIGEST_LENGTH];
(void)CC_SHA256( [databytes], (CC_LONG)[datalength], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA256_DIGEST_LENGTH] );
}
- (NSData*) _runData:(NSData*)keyData Cryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus*) status
{
size_tbufsize =CCCryptorGetOutputLength( cryptor, (size_t)[keyDatalength],true);
void* buf =malloc( bufsize );
size_tbufused =0;
size_tbytesTotal =0;
*status =CCCryptorUpdate( cryptor, [keyDatabytes], (size_t)[keyDatalength],
buf, bufsize, &bufused );
if( *status !=kCCSuccess)
{
free( buf );
return(nil);
}
bytesTotal += bufused;
// From Brent Royal-Gordon (Twitter: architechies):
// Need to update buf ptr past used bytes when calling CCCryptorFinal()
*status =CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
if( *status !=kCCSuccess)
{
free( buf );
return(nil);
}
bytesTotal += bufused;
return( [NSDatadataWithBytesNoCopy: buflength: bytesTotal] );
}
3,这样就可以使用afn进行上传了
NSMutableDictionary *paramDict=[[NSMutableDictionary alloc] init];
[paramDictsetValue:bodyforKey:@"data"];