澳门皇冠金沙网站-澳门皇冠844网站

热门关键词: 澳门皇冠金沙网站,澳门皇冠844网站

如何确保APP的安全性,支付开发填坑记之微信支

在开始谈技术干货之前,先大概说一下这次公司APP安全风波的始末,甩锅的理由有三,其一:创业公司凡事讲究敏捷开发,快速迭代上线,因此在完成功能需求之余无暇他顾;其二:安全问题应该为技术总监着重考虑的一点,但是(按照惯例,这里省略N字,不可描述);其三:后台接口定义也没有考虑到这一点,然而,从不要随便甩锅的好习惯来说,我还是要负起责任的,毕竟自己是iOS负责人,要对APP有个全面的把握.

iOS应用的安全性 常常被大家忽视。
iOS 如何做才安全:
1、首先,我们可以通过软件 下载 AppStore的ipa文件(苹果 把开发者上传的ipa进行了加壳再放到AppStore中),
得到ipa文件 可以分析APP 里包含的一些资源,如:图片、plist文件、静态wap页、.bundle 等。
所以不要 在plist文件、项目中的静态文件中 存储关键的信息,如果要保存,记得加密(这样可以增加破解的难度)。

微信支付,支持的支付方式比较多:有扫码支付,刷卡支付,APP支付和公众号支付。其中,APP和网站上最常用的就是APP支付和公众号支付。前者集成在APP中,后者主要是为微信用户提供了另一种支付方式(需要在微信的内置浏览器中打开页面,再调起微信支付)。

简单的讲下事情经过,就是突然有一天下午,一个用户打电话给客服说自己买了一张998元的机票买错了,想退票,要求公司给他取消订单退钱,然后还把支付宝的网页支付记录发了过来(后来证实是PS过的).然后财务部那边查账之后发现这个用户的支付宝账号确实付款了,但实际付款的只有1元,然后公司财务就把事情反馈给了副总,然后整个技术部就炸锅了,都在各抒己见分析这个1元钱是怎么通过APP付款到公司账户的,因为机票订单是没有1元的.而且APP和支付宝给后台的回调都是支付成功的.根据唯物主义思想来推断,支付宝出错的概率远小于我们APP出错的概率,而且后台也没有被攻入的迹象,因此就把问题锁定在APP上了,然后我们用的POST请求(一些人说比较安全,其实不加密的话,安全性和GET请求比起来相差无几),我们部门的首席科学家直接说APP肯定是被反编译了,原话是"我找我阿里的朋友帮忙,分分钟就把APP反编译了,然后随便下单."当时听了这话我是懵逼的,虽然从技术可操作性来说,存在反编译的可能,但是分分钟不费吹灰之力就反编译这种说法我是不太能接受的,然后就有了后边我自己攻击自己APP的举动.

2、我们可以用软件 查看 APP的沙盒,查看里面存储的 文件:sqlite、plist(NSUserdefault会存到Library下的Preferences中 的 plist文件中)、图片等,NSUserdefault 中不要保存关键信息,如果要保存,还是加密吧。。sqlite也是这样子的。

微信支付,支持的支付方式比较多:有扫码支付,刷卡支付,APP支付和公众号支付。其中,APP和网站上最常用的就是APP支付和公众号支付。前者集成在APP中,后者主要是为微信用户提供了另一种支付方式(需要在微信的内置浏览器中打开页面,再调起微信支付)。

我的分析就是反编译太麻烦,不容易实施,而且即使反编译出来了,一个类名一个方法名的去解析APP也很累,所以就从相对好实施的篡改网络请求及返回数据下手!之前看过唐巧大神的一篇关于Charles的使用讲解,不过当时是用来简单的抓别人的包,用点数据就放下了,现在就拿来实践一下篡改数据这个功能,首先安装好Charles,然后按部就班的把Charles设置为自己mac电脑的代理,

3、 用 工具 对加壳的ipa 进行脱壳(越狱手机 直接用PP助手下载的就是 脱壳的ipa),再用IDA、Hopper 进行反编译,进行分析 ,可以得到 近乎易懂的 伪代码。
所以 不要在 代码 中保存关键信息,比如接口通信中 AES加密的密钥,可以通过接口获取 这些关键数据。
如果要保存关键数据(比如:密钥 等),可以保存加密后的关键数据,运行的时候进行解密获取真实的数据。这样可以增加破解的难度。
密钥要定期更换。比如 3个月 或半年换一次,如果密钥是从接口获取的,直接修改服务端就可以了。
如果密钥是写在代码里的。就等APP升级新的版本的时候,新版本的APP和其对应的接口版本 修改为新的密钥 就可以了。旧的接口版本和APP版本还用以前的密钥,等强制更新的时候才会失效。

同样的,微信的APP支付和支付宝的APP支付也是很简单:

澳门皇冠844网站 1img然后手机连自己电脑wifi,或者跟电脑连接同一个wifi都可以,然后设置手机的代理,让你手机的网络请求都经过Charles,服务器里填写的是电脑的IP地址,澳门皇冠844网站 2img端口默认的就是8888:澳门皇冠844网站 3img这样就可以抓到APP跟服务器之间的网络请求了.然后在查看请求之后去使用篡改功能,这里就演示一下篡改一个页面的数据澳门皇冠844网站 4img这里的第一个票价是12500,下边是拦截到的请求澳门皇冠844网站 5img给这个IP地址对应的8080端口的请求都加上断点,点击那个Breakpoints,然后当下一次请求进来的时候,就可以直接篡改数据澳门皇冠844网站 6img篡改数据的步骤可以看下方的gif图:澳门皇冠844网站 7img之后点击"Execute",返回给APP数据,这样APP展示的页面就变成了:澳门皇冠844网站 8img到这里用户的骗术就被还原了,当然后边还需要篡改一些数据才能成功去下单支付这个1元订单,细节就不在赘述了澳门皇冠844网站 9img那个支付宝支付显示不全是因为iOS10字变宽了,当然支付成功之后的心情是很复杂的,毕竟自己的APP被这么轻易搞出问题了,大家可以设身处地想一下哈,后边重点来了,讲解一下小公司的解决方案.因为开发压力比较大,所以要考虑性价比比较高的方案,这里就暂时舍弃了HTTPS,运用了实施起来相对简单的MD5加密,这里有两种情况,下载加密和上传加密,比如说刚才看到的订单列表就属于下载加密,要确保订单列表数据一旦被篡改就不去使用,而点击立即支付的下单动作就是上传加密,要确保传给服务器的下单参数一旦被篡改就不去使用,MD5加密的原理就不在这里讲了,因为我之前的文章JSPatch里已经讲过了,主要说一下具体的实施细节以及过程中遇到的小坑,首先是下载加密:澳门皇冠844网站 10img我用的网络请求是自己封装的AFN,然后这里设置一下直接字符串取值,不要转成JSON:manager.responseSerializer = [AFHTTPResponseSerializer serializer];取出HTTP Header里的验证字串:NSDictionary *headerDic = [operation.response allHeaderFields];``NSString *rsaValue = headerDic[@"rsaValue"];然后取值:NSString *responseObjectStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];加密:NSString *md5Str = [NSString stringWithFormat:@"%@%@", responseObjectStr, md5SaltValue];然后进行比对校验[[md5Str getMd5_32Bit] isEqualToString:headerDic[@"rsaValue"]]然后是上传加密:澳门皇冠844网站 11img把所有参数转换为String:String *jsonString = [self.orderModel yy_modelToJSONString];加密:NSString *md5Value = [[NSString stringWithFormat:@"%@%@",jsonString,md5SaltValue] getMd5_32Bit];设置请求头:[manager.requestSerializer setValue:md5Value forHTTPHeaderField:@"rsaValue"];到这里,这篇文章算是告一段落,后边应该会更新一系列安全相关的文章,不过需要一个我去学习然后理解然后实践的过程~下一篇是动手去反编译自己APP开始踩坑之旅.当然都是我自己的浅显青铜操作,欢迎同学们指点及大神们一笑而过.

如果一个APP 一个密钥用上几年都不变 ,是很危险的。离职的人员都可以直接用以前 的代码 来获取相关的数据。特别是 支付相关的,有的服务端甚至没有 去校验支付的金额或其他数据,导致 离职人员用1分钱 可以买到 任何价格的 线上产品。。

APP支付

商户系统和微信支付系统主要交互说明:

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。

步骤2:商户后台收到用户支付单,调用微信 支付统一 下单接口。参见 【统一下单API】 。

步骤3:统一下单接口返回正常的 prepay_id ,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为 appId , partnerId , prepayId , nonceStr , timeStamp , package 。 注意:package的值格式为Sign=WXPay

步骤4:商户APP调起微信支付。

步骤5:商户后台接收支付通知。

步骤6:商户后台查询支付结果。

这里主要的还是后台干活(获取 prepay_id ,生成随机字符串 nonceStr 和时间戳 timeStamp, appId 和 partnerId 均能在后台管理中查看。)

后台的步骤也很简洁,就是上述中的步骤1,2。

  1. 获取 prepayId :

    1. 设置获取 prepayId 所需参数。

    此处需要调用微信的统一下单接口。这个过程, 官方文档 已经写得十分之详细了,包括调用的接口API地址,需要传递的参数(必要和非必要的参数),还有返回结果也写得很清楚。

    以下是我在实际项目开发中传入的参数。

    澳门皇冠844网站 12

    澳门皇冠844网站 13

    1. 签名。

    签名都差不多,都是先将所有的带签名的参数进行字典排序。

    ksort($data);
    

    然后将参数以 {key}={value} 的组合形式,用 & 连接。

    $a = array();
    foreach ($data as $k => $v) {
        if ((string) $v === '') {
            continue;
        }
        $a[] = "{$k}={$v}";
    }
    
    $a = implode('&', $a);
    

    最后拼上 &key={Your apiKey} ,然后对整串字符串进行MD5加密即可。

    $sign = strtoupper(md5($a));
    
  2. 将拼好的数据,以 XML 的格式发送给微信,请求 prepayId

    没错,就是要转成 XML 格式再发送。

    但是,这个XML格式很简单,只需要进行简单的拼接即可:

    public functionarrayToXml(array $data)
    {
        $xml = "<xml>";
        foreach ($data as $k => $v) {
            if (is_numeric($v)) {
                $xml .= "<{$k}>{$v}</{$k}>";
            } else {
                $xml .= "<{$k}><![CDATA[{$v}]]></{$k}>";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }
    

    #### 参数值用XML转义即可,CDATA标签用于说明数据不被XML解析器解析。。

    然后请求统一下单API即可(url = https://api.mch.weixin.qq.com/pay/unifiedorder )

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    $response = curl_exec($ch);
    if (!$response) {
        throw new Exception('CURL Error: ' . curl_errno($ch));
    }
    curl_close($ch);
    

    请求回来的数据也为XML格式,只需要简单做下处理,转换成array即可:

    public functionxmlToArray($xml){
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
    

    如果返回值中的 return_code 和 result_code 都为 SUCCESS 的时候会返回 交易类型 trade_type 和 预支付交易会话标识 prepayId 。到这里,我们就可以获取到 prepayId 。

  3. 将获取的 prepayId 与其他参数拼接,返回给APP即可。

    $params = array();
    // 商户号
    $params['appid'] = $this->config->appId;
    // 时间戳
    $params['timestamp'] = '' . time();
    // 随机字符串
    $params['noncestr'] = md5(uniqid(mt_rand(), true));
    // 固定为 'Sign=WXPay'
    $params['package'] = 'Sign=WXPay';
    // 步骤3获取的预支付交易会话标识
    $params['prepayid'] = $prepayId;
    // 合作伙伴id
    $params['partnerid'] = $this->config->partnerId;
    // 步骤2生成的签名。
    $params['sign'] = $this->sign($params);
    

微信APP支付,后台需要干的活到这里就暂时结束了(因为还有支付成功后的异步通知商户后面再讲)

最好能 进行 代码混淆,能增加反编译的难度,当然只是增加了难度,还是能破解的。

jsapi支付

下面就是web版的微信支付(公司项目是在微信浏览器内,选择微信支付后,在微信中调起的微信支付)

澳门皇冠844网站 14

web版微信支付的步骤和APP的大同小异,也是现获取 prepayId ,再在页面中,调用jsapi进行支付。

但是,此处有2个坑

4、用https也是可以被抓包并解析的,所以网络通信 一定要用自己的加密方式 进行加密。
接口返回的数据 最好也进行 加密。

坑1: 支付时出现 appid and openid not match 的报错

原因非常的简单,就是支付时所获取的 openid 在并不属于支付的商户。

这个 openid 为微信用户在商户对应appid下的唯一标识。也就是说,必须根据支付的商户的 appid 去获取用户的 openid 。

因为业务逻辑需要,项目中用于 微信登录用的公众号A 与 用于支付的公众号B (其实还和开放平台用于APP支付的 appId 也是不一样的)是不一样的,虽然所获取unionid是一致,但是 openid 是不!一!样!的!所以,在获取 openid 时,需要使用当前支付时所用到的 appid 去请求用户的 openid ,同时,请求 openid 后的回调也必须是 支付商户 后台所设置好的回调地址,要不然就会报 redirect_uri 参数错误 的错误。

可以这么说:无论 你怎么做,理论上都是可以破解的,但是 破解人员也要考虑成本。。
有的银行的APP,只用了https,通信都不加密,很容易就拿到明文数据了。有的APP里的各种数据都 采用复杂的加密算法,破解人员看到都烦,去破解这个APP的时间还不如去搞其他的几个APP。

坑2: 参数名大小写不一致。

澳门皇冠844网站 15

↑ APP支付的参数

澳门皇冠844网站 16

↑ web支付的参数

仔细看看划横线的地方。没错,app中的参数的key全是小写,web支付中的key则为驼峰命名方式。而且,签名方式 signType 是必填的, 签名的字段也变成了 paySign ,其中 package 的值也是不一样,APP支付是固定的值,web支付则为 prepayId ,这也要注意。当然, 官方文档 也是很详细的说明,但是需要细心观察(所以说嘛,还是直接拷贝必填项最保险了2333)。

澳门皇冠844网站,拿到所有参数后,就可以在页面中发起微信支付的请求了。

代码可以直接使用官方提供的js代码

functiononBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', YOUR_PARAMS,
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
               // success_callback
           }     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

其中 YOUR_PARAMS 是参数转换成json格式直接渲染至页面即可。

如果参数没错的话,那么就可以顺利的调起支付窗口了。

一、ipa文件
1、AppStore里的ipa包 可以通过 iTunes 下载到电脑。iOS8.3以下系统的非越狱的手机上,可以用MAC上的PP助手等软件,直接把手机上的ipa文件(包含沙盒里的存储文件)拷贝到电脑。
如果是越狱手机,都可以用PP助手、itools直接把ipa导出到电脑,并且可以用PP助手、iExplorer、itools这些工具 查看 iOS的系统目录。

坑3: APP支付和jsapi支付不是同一个号

APP支付是在开放平台中申请下来的,appId和apiKey都是不一样的。而jsapi支付实质就是公众号支付,是在公众平台中申请得到的。所以,在这里,需要注意一下。

重要的来了,能体现后台的重要性的地方终于来了 —

MAC上安装 iExplorer软件,用iExplorer 可以看到 手机(非越狱也可以) 在 iTunes上备份的内容。
如果你在帮测试美女的手机 调试问题的时候, 在 iTunes上设置 “连接次iPhone时自动同步”(或者点击 备份到本地电脑),默认该手机上的照片、短信等内容都会备份到你的电脑上,用 iExplorer 就可以看到 这位 美女的隐私。
曾经有次不小心看到同事的隐私信息,所以现在都比较注意这块,避免引发误会。

支付结果的异步通知

官方文档 写得也很详细了(不得不说,微信的开发文档真的很清晰。很容易找到。就是没有详细的步骤区分)。

首先需要申明的是:异步通知的URL是 必须能在公网访问 的,而且,必须 不能携带参数 。

也就是说,  是没问题的,但是  这样的URL是不行的。如果要想达到这种效果,要不服务器(Nginx , Apache)进行rewrite,要不在notify.php 中,手动修改 $_GET 中的参数。

返回的数据,都是一致的:

澳门皇冠844网站 17

这时候,商户后台拿到这些异步通知的数据进行简单的校验即可,然后修改商户中相应订单的支付状态。

  1. 校验返回码是否成功

    $d = $this->xmlToArray(file_get_contents('php://input'));
    if (empty($d)) {
        throw new Exception(__METHOD__);
    }
    if ($d['return_code'] != 'SUCCESS') {
        throw new Exception($d['return_msg']);
    }
    if ($d['result_code'] != 'SUCCESS') {
        throw new Exception("[{$d['err_code']}]{$d['err_code_des']}");
    }
    
  2. 对返回数据进行校验

    和请求 prepayId 时处理数据的方式差不多,先取出签名 sign ,然后除去签名后,进行字典排序,以 {key}={value} 的方式进行组合,并在最后加上 &key={apiKey} 得到待校验字符串,最后,将待校验字符串进行MD5加密,和签名进行比较,若一致则校验成功,并且支付成功,然后后台做相应操作。

    if (!$this->verify($d)) {
        throw new Exception("Invalid signature");
    }
    
    // 验证函数
    if (empty($d['sign'])) {
        return false;
    }
    $sign = $d['sign'];
    unset($d['sign']);
    return $sign == $this->sign($d);
    

2、拿到ipa文件后,解压缩,得到.app文件,右键显示包内容,可以看到里面的app中的图片、js、plist、静态H5页 等资源。
比如 你要 用微信里的默认表情包,解压微信的ipa包就可以获取到。

微信退款

有支付肯定就会有退款。微信的退款操作也是很简单,而且退款速度非常快,测试时基本都是秒退。

但是退款是有注意事项的:

  1. 交易时间超过 一年 的订单无法提交退款;
  2. 微信支付退款支持单笔交易分多次退款,多次退款需要提交 原支付订单的商户订单号 和设置 不同的退款单号 。总退款金额不能超过用户实际支付金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号 。
  3. 退款请求需要证书 。

【证书获取方式:】

微信支付接口中,涉及资金回滚的接口会使用到商户证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全–>证书下载。

微信退款程序流程:

澳门皇冠844网站 18

  1. 设置退款时得参数。

    请求的参数有:

    1. appid : 公众账号ID
    2. mch_id : 商户号
    3. nonce_str : 随机字符串
    4. sign: 签名
    5. transaction_id / out_trade_no :微信订单号 / 商户订单号 二者中传其中一个即可。
    6. out_refund_no: 商户退款单号(由商户自行生成的唯一标识)
    7. total_fee:订单金额(单位为分)
    8. refund_fee:退款金额(单位为分),退款金额不能大于订单金额。
    9. op_user_id:操作员帐号, 默认为商户号

    签名还是老规矩(默认是MD5方式),先将所有参数进行字典排序,然后以 $key=$value 的形式用 & 字符拼接成字符串,最后将拼上 &key=YOUR_APIKEY 的待签名字符串进行MD5加密即可。

    澳门皇冠844网站 19

  2. 将参数列表转换成XML格式。

    澳门皇冠844网站 20

  3. 发送退款请求。

    退款请求需要携带微信上下载的证书,请保证证书存放路径外网不能直接访问。

    澳门皇冠844网站 21

  4. 解析请求结果。

    当返回的结果中, return_code 和 result_code 均为 SUCCESS ,即为退款申请成功。更多返回结果,请移步至 官网

3、iOS的系统目录和MAC上的都类似(类unix系统)。iOS系统的目录图:

结尾

微信支付的官方开发文档其实算是很详细了,传递的参数,返回结果,如果判断是否成功,都写的很好。只是,开发中的逻辑过程需要自己慢慢摸索,理清思路后,开发起来其实都是很迅速的。

但是,开发微信支付时,需要留个心,需要将所有涉及到的微信后台提供的数据小心保存(比如AppSecret,一当忘记只能重置。)

祝各位开发过程顺利进行。

澳门皇冠844网站 22

1.png

二、沙盒 中的数据
iPhone上 计算器的沙盒:

澳门皇冠844网站 23

2.png

.app文件:应用程序本身的数据,打包时候的一些资源文件(如:图片、plist等文件)、可执行文件。这个目录不会被iTunes同步。
Documents :存储不可再生 的关键数据。不会被iTunes同步
Library:保存配置文件和其他一些文件。NSUserDefault 会存储到 Library下的Preferences中 的 plist文件中。可以直接打开,所以 也不要在 NSUserDefault 中存一些 关键数据,或者 存储的时候 进行 AES等方式的加密。
Library/Caches可以用来保存可再生的数据,比如网络请求,用户需要负责删除对应文件。
这个目录(除了Library/Caches外)会被iTunes同步
tmp:临时文件。不需要的时候,手动将其内文件删除。(当应用不再运行的时候,系统可能会将此目录清空。)
这个目录不会被iTunes同步
存到沙盒的数据都是不安全的,关键数据一定 要做加密存储。

三、Reveal 工具:查看 任意APP 的UI结构
1、不越狱的手机 可以用 Reveal 来查看自己APP的UI结构。不能查看其他APP的UI结构。这里就不再描述了。

2、越狱手机 上可以查看 任何APP的UI结构。
在越狱的手机上,在 Cydia 搜索并安装 Reveal Loader,如果搜索不到。就 点下面的“软件源”,选择“BigBoss”,选择“全部软件包”,点右边R的字母,去一个个找到 Reveal Loader,放心吧,你一定能找到的,我用的iOS7.1的系统测试的,没问题。
安装完成后,打开“设置”页面,下拉到最底部,点击“Reveal”

澳门皇冠844网站 24

3.png

3、点击 Enabled Applictions 。然后选中 你想分析的APP。
4、确保iOS和OSX在同一个IP网段内。打开想分析的 APP,如果该APP已经启动,则关闭后再次启动
5、打开MAC上的 Reveal,选中 左上方列表里的 APP,比如QQ:

澳门皇冠844网站 25

4.png

6、如果 Reveal
左上方 一直显示:No Connection。说明iPhone上的 Reveal Loader 没安装成功,需要配置一下。

本文由澳门皇冠金沙网站发布于编辑程序,转载请注明出处:如何确保APP的安全性,支付开发填坑记之微信支