前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS参数签名:请求参数按照ASCII码从小到大排序、拼接、加密(递归的方式实现)案例:条码支付综合前置平台申请退款【修订版】

iOS参数签名:请求参数按照ASCII码从小到大排序、拼接、加密(递归的方式实现)案例:条码支付综合前置平台申请退款【修订版】

作者头像
公众号iOS逆向
发布2021-04-15 16:09:09
1.7K1
发布2021-04-15 16:09:09
举报
文章被收录于专栏:iOS逆向与安全

前言

支付类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参与排序。 (字典和数组独立排序)

  • 参数
代码语言:javascript
复制
    NSDictionary *params = @{@"sid" :  @"iOS逆向",
                             @"certificateInfoList" :  @"https://kunnan.blog.csdn.net/article/details/108195721" ,
                             @"storePicsList" : @"https://kunnan.blog.csdn.net" ,
                             };

  • 效果
代码语言:javascript
复制

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…)拼接而成,空值不传递,不参与签名组串。

代码语言:javascript
复制
<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>
代码语言:javascript
复制
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参与排序。 字典和数组独立排序

代码语言:javascript
复制
isPreAuth=false&isWipeZero=true&needTrade=falsetotalAmount=22

  • 处理key对应的Value是字典的情况
代码语言:javascript
复制
/**
 
 递归
 
 - 处理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类型进行分组,其中的子数组是字符串类型的话,就对其进行排序之后再重新组合到新的数组中。然后再进行遍历递归拼接

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS逆向 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • I、实现步骤
    • 1.1 签名原始串:按照参数名ASCII码从小到大排序并拼接[递归的方式进行实现]
    相关产品与服务
    SSL 证书
    腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档