天天看點

iOS參數簽名:請求參數按照ASCII碼從小到大排序、拼接、加密(遞歸的方式實作)案例:條碼支付綜合前置平台申請退款【修訂版】前言I、實作步驟

iOS參數簽名:請求參數按照ASCII碼從小到大排序、拼接、加密(遞歸的方式實作)案例:條碼支付綜合前置平台申請退款【修訂版】前言I、實作步驟

前言

支付類app為了安全起見,除了使用【防代理分析請求資料】,還可采用簽名的方式進一步進行限制防止請求和傳回封包被修改。

iOS請求安全防護【1、 防代理分析請求資料 2、SSL證書認證3、采用簽名禁止修改封包4、不在本地緩存網絡請求封包5、利用NSURLProtocol 攔截請求修改HTTPHeaderField】

1、iOS網絡請求安全優化:2、不走全局proxy的方案;3、允許不驗證SSL證書;4、攔截請求;5、DoH &DoT

1、iOS安全【 SSL證書驗證, 讓Charles再也無法抓你的請求資料】2、iOS逆向:【繞過證書校驗】

文章位址: https://blog.csdn.net/z929118967/article/details/102511852

  • 應用場景:防止請求參數被惡意修改

在對接第三方支付的時候,第三方會要求參數按照ASCII碼從小到大排序。

1、銀聯的退款接口簽名:https://kunnan.blog.csdn.net/article/details/115084885

◆ key:簽名時用機構對應的密鑰key

◆簽名算法:MD5,後續會相容SHA1、SHA256、HMAC等 2、微信支付接口簽名:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3

◆ key設定路徑:微信商戶平台(pay.weixin.qq.com)-->賬戶設定-->API安全-->密鑰設定

◆注:HMAC-SHA256簽名方式,部分語言的hmac方法生成結果二進制結果,需要調對應函數轉化為十六進制字元串

◆生成随機數算法:調用随機數函數生成,将得到的值轉換為字元串。

◆使用openssl指令來自己導出pem證書(p12 to pem):openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem

◆ 微信支付接口簽名校驗工具 :https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=20_1

  • 原文
https://blog.csdn.net/z929118967/article/details/108195721

從CSDN下載下傳demo位址:https://download.csdn.net/download/u011018979/15483107

1、demo 數組用[]表示,對象(字典)用{} 表示進行排序拼接。

2、數組排序可選,數組内部,隻對字元串元素進行排序,并不與字典key參與排序。 (字典和數組獨立排序)

  • 參數
NSDictionary *params = @{@"sid" :  @"iOS逆向",
                             @"certificateInfoList" :  @"https://kunnan.blog.csdn.net/article/details/108195721" ,
                             @"storePicsList" : @"https://kunnan.blog.csdn.net" ,
                             };

           

複制

  • 效果
2021-02-26 15:43:42.208991+0800 SignatureGenerator[16231:1928569] 按照參數名ASCII碼從小到大排序:《certificateInfoList=https://kunnan.blog.csdn.net/article/details/108195721&sid=iOS逆向&storePicsList=https://kunnan.blog.csdn.net》


2021-02-26 15:43:42.209280+0800 SignatureGenerator[16231:1928569] sign:195b9caecc41681ebd1b74261f858052

           

複制

I、實作步驟

為了保證資料傳輸過程中的資料真實性和完整性,我們需要對資料進行數字簽名,在接收簽名資料之後進行簽名校驗。

數字簽名有兩個步驟:

1、先按一定規則拼接要簽名的原始串,

2、再選擇具體的算法和密鑰計算出簽名結果(注意:簽名時将字元串轉化成位元組流時指定的編碼字元集應與參數charset一緻。)

  • 簽名原始串
所有參數按照字段名的ascii碼從小到大排序後使用QueryString(

URL鍵值對

)的格式(即key1=value1&key2=value2…)拼接而成,空值不傳遞,不參與簽名組串。
<xml>
<body><![CDATA[測試支付]]></body>
<mch_create_ip><![CDATA[127.0.0.1]]></mch_create_ip>
<mch_id><![CDATA[7551000001]]></mch_id>
<nonce_str><![CDATA[1409196838]]></nonce_str>
<out_trade_no><![CDATA[141903606228]]></out_trade_no>
<service><![CDATA[unified.trade.micropay]]></service>
<sign><![CDATA[52836FAD27E0813DAA4072A4BDA9F654]]></sign>
<total_fee><![CDATA[1]]></total_fee>
</xml>
           

複制

body=測試支付&mch_create_ip=127.0.0.1&mch_id=7551000001&nonce_str=1409196838&out_trade_no=
141903606228&service=unified.trade.micropay&total_fee=1

           

複制

1.1 簽名原始串:

按照參數名ASCII碼從小到大排序并拼接

[遞歸的方式進行實作]

設所有發送或者接收到的資料為集合M,将集合M内的參數和參數值按照參數名ASCII碼從小到大排序(字典序),使用QueryString的格式(即key1=value1&key2=value2…)拼接成字元串stringA。

1、demo 數組用[]表示,對象(字典)用{} 表示進行排序拼接。

2、數組排序可選,數組内部,隻對字元串元素進行排序,并不與字典key參與排序。 字典和數組獨立排序

isPreAuth=false&isWipeZero=true&needTrade=falsetotalAmount=22

           

複制

  • 處理key對應的Value是字典的情況
/**
 
 遞歸
 
 - 處理key對應的Value是字典的情況

     request body參數名ASCII碼從小到大排序(字典序),
 使用URL鍵值對的格式拼接成字元串    (key1=value1&key2=value2…)

 */
+ (NSString *)sortedDictionary:(NSMutableDictionary *)originParam {
    
    NSDictionary *dict = originParam;
    

    NSMutableString *contentString =[NSMutableString string];

    NSArray *keys = [dict allKeys];
    

    //按字母順序排序

    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

        return [obj1 compare:obj2 options:NSNumericSearch];

    }];

    //拼接字元串

    for (NSString *categoryId in sortedArray) {

#pragma mark - ******** todo value區分數組[,]、字元串、字段對象{}
        

        id  categoryIdV = [dict objectForKey:categoryId];
        
        
//
        if( [categoryIdV isKindOfClass:NSString.class]){
            

        
        }
        else         if( [categoryIdV isKindOfClass:NSDictionary.class]){
            
            
            categoryIdV = [self sortedDictionary:categoryIdV];
            
            categoryIdV = [NSString stringWithFormat:@"%@%@%@",@"{",categoryIdV,@"}"];
            
            
            
        }
        // 數組就[]
        
        else         if( [categoryIdV isKindOfClass:NSArray.class]){
            

            
            categoryIdV =   [self sortedDictionaryArr:categoryIdV];
            
            
            
        }

        
        
        if ([contentString length] <= 0) {
            //第一個參數
        }else{
            [contentString appendString:@"&"];
        }
        
        
        [contentString appendFormat:@"%@=%@", categoryId,categoryIdV ];
        
        


    }

    
    NSLog(@"%@",contentString);
    return contentString;
}

           

複制

  • 處理key對應的Value是數組的情況

簽名數組ASCII碼排序的地方

相關問題解答:https://kunnan.blog.csdn.net/article/details/115355062

新增集合元素排序【可選】:對于數組排序,先按照數組元素的class類型進行分組,其中的子數組是字元串類型的話,就對其進行排序之後再重新組合到新的數組中。然後再進行周遊遞歸拼接