美文网首页程序员
iOS 接口加密方法-ASE256和数字签名

iOS 接口加密方法-ASE256和数字签名

作者: iOS大熊猫 | 来源:发表于2020-05-15 13:36 被阅读0次

    //这是需要加密的字典,里面存储这需要上传的参数

    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"];

    相关文章

      网友评论

        本文标题:iOS 接口加密方法-ASE256和数字签名

        本文链接:https://www.haomeiwen.com/subject/jfccohtx.html