iOS接入快盤的HMAC-SHA1授權認證失敗解決方案

最近幫別人看了一個使用HMAC-SHA1 進行加密授權快盤的一個認證咱筛,經(jīng)過測試,第一步獲取 oAuth-token 就會出現(xiàn)錯誤,錯誤原因是饭于,簽名失敗,也就是說我們的簽名某個地方錯誤了维蒙,簽名這個地方看著好做掰吕,其實一步走錯,就會全部錯哦木西,我們就完全跳進坑了


一畴栖、 下面我們看一下,第一步我們要怎么去接入快盤

  1. 點擊進入快盤開發(fā)者中心
  2. 我們進行一個賬號注冊八千,添加一個應用 后然后獲取對應的 auth_consumer_keyconsumer_secret
  3. 點擊進入開發(fā)者文檔一欄吗讶,這些文檔可以在使用的時候慢慢研究
  4. 點擊 左側(cè)的 OAuth 協(xié)議 【RFC58493.4 HMAC-SHA1】最下面的簽名生成算法

我們會看到如下幾個重要的地方

第一步授權重要步驟

其實這個加密規(guī)則還算簡單,就是encode 稍微有點麻煩恋捆,我們感覺快盤的其實只是提供了一些API接口照皆,并沒有什么SDK,所以我們要完全按照文檔提示的操作步驟走

二沸停、簽名算法的生成

  • 我們先了解一下官方API的簽名膜毁,官方提供給我們的是Python 寫的實例,有些不懂的似乎看的不是太懂愤钾。我們看下官方提供的思路
假設服務器地址為 openapi.kuaipan.cn瘟滨,現(xiàn)在需要向 
http://openapi.kuaipan.cn/1/fileops/create_folder 用GET方法發(fā)
出請求,請求參數(shù) (parameters) 如下:
{
        'oauth_version': '1.0', 
        'oauth_token': 'fa361a4a1dfc4a739869020e586582f9', 
        'oauth_signature_method': 'HMAC-SHA1', 
        'oauth_nonce': '58456623', 
        'oauth_timestamp': 1328881571, 
        'oauth_consumer_key': '79a7578ce6cf4a6fa27dbf30c6324df4', 
        'path': '/test@kingsoft.com', 
        'root': 'kuaipan'
}
//Python  簽名加密格式:
http_method + "&" +
url_encode( base_uri ) + "&" +
url_encode(
        “&”.join(
                sort( [url_encode ( k ) + "=" +url_encode ( v ) for k, v in paramesters.items() ]
        )
)



我們將加密規(guī)則翻譯過來看一下iOS中我們要如何寫(拼接字符串參數(shù)) 步驟如下:(下面步驟都是拼接關系能颁,我們進行拆分)

  1. HTTPMethod: GET 大寫
  2. 地址符號: &
  3. url_encode: base_uri utf8string] 對基地址進行URL編碼
  4. join 前面的&:此處表示將一個數(shù)組拼接起來的意思杂瘸,緊跟后面的sort 函數(shù)結(jié)果 ,并不是 此處用 & 去連接
  5. sort : 按照官方給予的解釋就是將參數(shù)按照 字典的ASCII 碼進行Key值排序伙菊,例子給出的是升序排列組合败玉, Python 所謂的字典就是Map 集合,OC對應的就是NSDictionary -字典
  6. sort函數(shù)內(nèi)部: 里面的for 循環(huán)代表是循環(huán)遍歷字典镜硕,并且每個鍵值對 都進行一次URL encode运翼。循環(huán)之后的鍵值對經(jīng)過 & 進行連接到一起
  7. 最終我們將4、5兴枯、6的最終拼接完成的字符串血淌,再次經(jīng)過一次URL ,encdoe 财剖,就得到官方所說的原串的編碼拼接完畢悠夯。

我們看一下官方生成的簽名格式:

GET&http%3A%2F%2Fopenapi.kuaipan.cn%2F1%2Ffileops%2Fcre
ate_folder&oauth_consumer_key%3D79a7578ce6cf4a6fa27
dbf30c6324df4%26oauth_nonce%3D58456623%26oauth_signat
ure_method%3DHMAC-
SHA1%26oauth_timestamp%3D1328881571
%26oauth_token%3Dfa361a4a1dfc4a739869020e586582f9%26
oauth_version%3D1.0%26path%3D%252Ftest%2540kingsoft.co
m%26root%3Dkuaipan

原串編碼組合完畢形式如上所示:

  • 原串編碼完畢,我們使用HMAC-SHA1進行秘鑰加密:
  1. 生成簽名加密的秘鑰峰伙,格式如下:
    然后生成簽名加密的密鑰(記得有個&)疗疟,注意假如沒有 oauth_token的話,"&"之后的部分是不用包含的:
    c7ed87c12e784e48983e3bcdc6889dad&0183ce137e4d4170b2ac19d3a9fda677
  2. 使用密鑰通過HMAC-SHA1算法簽名字符基串瞳氓,生成簽名(先生成數(shù)字簽名策彤,然后再用base64 encode):
    pa7Fuh9GQnsPc+Lcn+Qu6G7LVEU=
  3. 最后把urlencode后的簽名作為oauth_signature的值,向連接發(fā)出請求:
    url_encode(auth_signature) 進行最后一次編碼匣摘,現(xiàn)在就可以直接發(fā)送請求了:
    通過終端或者通過官方提供的平臺都可以測試:
    終端命令:
curl –k 
"http://openapi.kuaipan.cn/1/fileops/create_folder?oauth_version=1.0&oauth_signature=pa7Fuh9GQnsPc%2BLcn
%2BQu6G7LVEU%3D&oauth_token=fa361a4a1dfc4a739869020e586582f9&oauth_signature_method=HMAC-SHA1&oauth_nonc
e=58456623&oauth_timestamp=1328881571&path=%2Ftest%40kingsoft.com&oauth_consumer_key=79a7578ce6cf4a6fa27
dbf30c6324df4&root=kuaipan"

三店诗、iOS中如何去操作這些加密規(guī)則?

我們直接代碼接入測試:

  1. 準備好申請的Key 和 Secret 音榜,我們這里只做第一步的簽名認證:
    獲取requestToken
    baseUri :
static NSString  * baseUrl = @"https://openapi.kuaipan.cn/open/requestToken";

參數(shù)準備:

 NSDictionary * prama = @{@"oauth_consumer_key":@"xcVaIWFCPRTVabGH",
                              @"oauth_signature_method":@"HMAC-SHA1",
                              @"oauth_timestamp":[self dateString],
                              @"oauth_nonce":[self onceString],
                              @"oauth_version":@"1.0",
                              };

涉及到的兩個方法 dateStringonceString

- (NSString *)dateString{
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval a=[dat timeIntervalSince1970]*1000;
    NSString *timeString = [NSString stringWithFormat:@"%.f", a];

    NSRange rang = {0,10};
    NSString *subString = [timeString substringWithRange:rang];

    return subString;
}

- (NSString *)onceString{
    NSString *string = [[NSString alloc]init];
    for (int i = 0; i<8; i++) {
        int number = arc4random() % 25;
        if (number < 10) {
            int figure = (arc4random() % 26) + 97;
            char character = figure;
            NSString *tempString = [NSString stringWithFormat:@"%c", character];
            string = [string stringByAppendingString:tempString];
            if (figure%2==0) {
                [string uppercaseString];
            }
        }else {

            int figure = arc4random() % 10;
            NSString *tempString = [NSString stringWithFormat:@"%d", figure];
            string = [string stringByAppendingString:tempString];
        }
    }
    return string;

}

我們所用到的URL——Encode方法如下

- (NSString *)encodeToPercentEscapeString: (NSString *) input
{
    NSString*
    outputStr = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(

                                                                             NULL, /* allocator */

                                                                             (__bridge CFStringRef)input,

                                                                             NULL, /* charactersToLeaveUnescaped */

                                                                             (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                             
                                                                             kCFStringEncodingUTF8);
    
    
    return  outputStr;
}

HMAC-SHA1 簽名之后庞瘸,使用Base64編碼
簽名格式: HMAC-SHA1(原串,秘鑰) -> Base64 編碼
使用HMAC赠叼,時需要導入一下兩個類庫

#import <CommonCrypto/CommonHMAC.h>
#import <CommonCrypto/CommonCryptor.h>
+ (NSString *)hmac_sha1:(NSString *)key text:(NSString *)text{

    const char *cKey  = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [text cStringUsingEncoding:NSUTF8StringEncoding];

    char cHMAC[CC_SHA1_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:CC_SHA1_DIGEST_LENGTH];
    NSString *hash = [HMAC base64Encoding];//base64Encoding函數(shù)在NSData+Base64中定義(NSData+Base64網(wǎng)上有很多資源)

    return hash;
}
  • 下面我們進行對參數(shù)進行排序:代碼如下:
 NSArray * keyArray = [prama allKeys];
     NSArray * sortArray = [keyArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
         return [obj1 compare:obj2 options:NSLiteralSearch];

     }];
  • 字典排序完畢擦囊,我們要進行組合违霞,并對其采用URL編碼:
 NSMutableString * appendString = [NSMutableString string];

     [appendString appendString:@"GET&"];
     [appendString appendString:[self encodeToPercentEscapeString:baseUrl]];

     [appendString appendString:@"&"];
     NSMutableArray * tempArray = [NSMutableArray array];

     for (NSString * keys in sortArray) {
         [tempArray addObject:[NSString stringWithFormat:@"%@=%@",[self encodeToPercentEscapeString:keys],[self encodeToPercentEscapeString:prama[keys]]]];
     }
    NSString * comments  =  [tempArray componentsJoinedByString:@"&"];
     
     NSLog(@"com = %@",comments);
     [appendString appendString:[self encodeToPercentEscapeString:comments]];
  • 下面進行HMAC-SHA1簽名:
NSString * macsha = [self.class hmac_sha1:@"申請應用所獲得consumer_secret&" text:appendString];
 NSString * praurl = [NSString stringWithFormat:@"oauth_signature=%@&oauth_consumer_key=%@&oauth_nonce=%@&oauth_signature_method=%@&oauth_timestamp=%@&oauth_version=%@",[self encodeToPercentEscapeString:macsha],prama[@"oauth_consumer_key"],prama[@"oauth_nonce"],prama[@"oauth_signature_method"],prama[@"oauth_timestamp"],prama[@"oauth_version"]];
//     NSLog(@"prama = %@",praurl);
NSString * replceurl = [NSString stringWithFormat:@"%@?%@",baseUrl,praurl];
  • 簽名組合完畢,進行如下請求驗證獲取第一次的Token:
 NSURL * url = [NSURL URLWithString:replceurl];
     NSLog(@"url = %@",url);

     NSMutableURLRequest * requestUrl = [NSMutableURLRequest requestWithURL:url];
     [requestUrl setHTTPMethod:@"GET"];
     NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
     NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];

     NSURLSessionDataTask * task = [session dataTaskWithRequest:requestUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         if (data) {
             NSLog(@"有數(shù)據(jù)");
             NSString * string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
             NSLog(@"string1 = %@",string);
         }else{
             NSString * string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
             NSLog(@"string2 = %@",string);

         }
         NSLog(@"responce = %d",[(NSHTTPURLResponse *)response statusCode]);

         if (error) {
             NSLog(@"error = %@",[error localizedFailureReason]);
         }

     }];
     [task resume];

如果在請求中返回如下 code :

配置正確的情況下會出現(xiàn) 401 簽名的問題

如圖瞬场,選中的部分基本上是簽名錯誤會返回的买鸽,這個問題看著很簡單,因為如果不是按照規(guī)定的編碼順序贯被,這個問題或者你要看上一天兩天了眼五,我在幫他調(diào)試的時候,最后一步的因為一個參數(shù)未編碼彤灶,導致多浪費了半天時間看幼,真的是自己挖坑哦。

總結(jié):

以上是快盤接入APP進行的一個簽名授權驗證幌陕, 后續(xù)一直按照如上方法诵姜,一直到獲取到accessToken 為止,如果還有不明白的苞轿,請留言茅诱!
如果以上有寫錯的地方,還望指出搬卒,給一些需要的人一些幫助瑟俭。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市契邀,隨后出現(xiàn)的幾起案子摆寄,更是在濱河造成了極大的恐慌踊餐,老刑警劉巖司浪,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乒融,居然都是意外死亡古戴,警方通過查閱死者的電腦和手機欠橘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來现恼,“玉大人肃续,你說我怎么就攤上這事〔媾郏” “怎么了始锚?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喳逛。 經(jīng)常有香客問我瞧捌,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任姐呐,我火速辦了婚禮殿怜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘皮钠。我一直安慰自己稳捆,他們只是感情好赠法,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布麦轰。 她就那樣靜靜地躺著,像睡著了一般砖织。 火紅的嫁衣襯著肌膚如雪款侵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天侧纯,我揣著相機與錄音新锈,去河邊找鬼。 笑死眶熬,一個胖子當著我的面吹牛妹笆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娜氏,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拳缠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贸弥?” 一聲冷哼從身側(cè)響起窟坐,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绵疲,沒想到半個月后哲鸳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡盔憨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年徙菠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郁岩。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡婿奔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出驯用,到底是詐尸還是另有隱情脸秽,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布蝴乔,位于F島的核電站记餐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏薇正。R本人自食惡果不足惜片酝,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一囚衔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雕沿,春花似錦练湿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疾渣,卻和暖如春篡诽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榴捡。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工杈女, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吊圾。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓达椰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親项乒。 傳聞我的和親對象是個殘疾皇子啰劲,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容