AES接口加密

項(xiàng)目里有些時(shí)候需要用AES來進(jìn)行接口加密,密鑰分為固定密鑰和動(dòng)態(tài)密鑰嚎莉,一般固定密鑰寫死在app內(nèi)腿椎,將登錄的信息用固定密鑰加密桌硫,放在登錄的時(shí)候進(jìn)行驗(yàn)證,驗(yàn)證通過后啃炸,會(huì)返回動(dòng)態(tài)密鑰铆隘,前端保存下來,調(diào)用加密接口時(shí)南用,用動(dòng)態(tài)密鑰進(jìn)行加密膀钠。

首先是 AES 加密類(.h):

#import <Foundation/Foundation.h>

@interface AES128 : NSObject

+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key;//加密
+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key; //解密
@end

接著是 .m 文件

#import "AES128.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation AES128

+( NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding|kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        // 對(duì)加密后的數(shù)據(jù)進(jìn)行 base64 編碼
        return [[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    }
    free(buffer);
    return nil;
}

+ (NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key; //解密
{
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSData *data = [[NSData alloc] initWithBase64EncodedString:encryptText options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          0x0000|kCCOptionECBMode|kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        return [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:buffer length:numBytesCrypted] encoding:NSUTF8StringEncoding];
    }
    free(buffer);
    return nil;
    
}
@end

接著就是需要加密的接口了,一般寫在公共的網(wǎng)絡(luò)請(qǐng)求類里裹虫,順便說一下肿嘲,一般加密接口都是 POST 請(qǐng)求,一般還需要帶 token 請(qǐng)求頭恒界,設(shè)備信息等等睦刃,涉及到別的類,就不寫進(jìn)來了十酣。

    // 創(chuàng)建會(huì)話管理者
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    // 設(shè)置請(qǐng)求方式為 POST 并填入 url 地址(要對(duì) url 處理涩拙,記得寫在前面,不然給 url 加后綴沒用)
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:url parameters:nil error:nil];

    // 判斷要請(qǐng)求的接口是不是登錄加密接口
    NSString *keyToken = @"";
    if ([url containsString:sign_in_phone_pass_URL] || [url containsString:sign_in_mail_pass_URL] || [url containsString:sign_up_phone_pass_URL] || [url containsString:sign_up_mail_pass_URL]) {
        // 是登錄加密接口耸采,使用固定密鑰
        keyToken = KeyToken;
    }
    else {
        // 不是登錄加密接口兴泥,使用保存在 userDeafult 的動(dòng)態(tài)密鑰
        keyToken = [UserInfoTool shareInstance].keyToken;
    }
    
    // 這句代碼是把字典轉(zhuǎn) JSON 字符串,params 是你要傳的參數(shù)字典
    NSString *str = [Utils convertToJsonData:params];

    // 將 JSON 字符串進(jìn)行 AES 加密
    NSString *AesStr = [AES128 AES128Encrypt:str key:keyToken];
    // 設(shè)置接收格式
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    // 設(shè)置body
    [request setHTTPBody:[AesStr dataUsingEncoding:NSUTF8StringEncoding]];
    AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
    responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
                                                                      @"text/html",
                                                                      @"text/json",
                                                                      @"text/javascript",
                                                                      @"text/plain",
                                                                      nil];
    manager.responseSerializer = responseSerializer;
    
    // 需要使用 dataTask 的方式請(qǐng)求
    [[manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
        
    } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
        
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        if (!error) {
            if (responseObject) {
                // 把返回對(duì)象轉(zhuǎn)成 JSON虾宇,再轉(zhuǎn)成字典
                id json = [self decrypeJsonWithData:responseObject];
                if ([json isKindOfClass:[NSDictionary class]]) {
                    NSDictionary *dic = (NSDictionary *)json;
                    // 把轉(zhuǎn)化成功的字典回調(diào)出去
                    [self successWithData:dic success:success failure:failure];
                }
            }
        }
        else {
            errors(error);
            [self failureWithError:error];
        }
    }] resume];
- (id)decrypeJsonWithData:(NSData *)data {
    // 轉(zhuǎn)成字符串
    NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    // 轉(zhuǎn)成json對(duì)象
    return [NSJSONSerialization JSONObjectWithData:[jsonStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搓彻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旭贬,老刑警劉巖怔接,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異稀轨,居然都是意外死亡扼脐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門奋刽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓦侮,“玉大人,你說我怎么就攤上這事佣谐《抢簦” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵狭魂,是天一觀的道長罚攀。 經(jīng)常有香客問我,道長坞生,這世上最難降的妖魔是什么是己? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任宙地,我火速辦了婚禮宅粥,結(jié)果婚禮上秽梅,老公的妹妹穿的比我還像新娘企垦。我一直安慰自己钞诡,他們只是感情好接箫,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般九默。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乙各,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼循签。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杆查。 我是一名探鬼主播崖蜜,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼舔琅,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼课蔬!你這毒婦竟也來了流昏?” 一聲冷哼從身側(cè)響起谚鄙,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤刁绒,失蹤者是張志新(化名)和其女友劉穎闷营,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體知市,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粮坞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了初狰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莫杈。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奢入,靈堂內(nèi)的尸體忽然破棺而出筝闹,到底是詐尸還是另有隱情,我是刑警寧澤腥光,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布关顷,位于F島的核電站,受9級(jí)特大地震影響武福,放射性物質(zhì)發(fā)生泄漏议双。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一捉片、第九天 我趴在偏房一處隱蔽的房頂上張望平痰。 院中可真熱鬧汞舱,春花似錦、人聲如沸宗雇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赔蒲。三九已至泌神,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間舞虱,已是汗流浹背欢际。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矾兜,地道東北人幼苛。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像焕刮,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子墙杯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349