背景
不久前,为了方便在fiddler中查看加密的业务请求,笔者开发了fiddler的解密插件。该插件可以在fiddler中以明文形式查看sdk业务请求和打点数据,方便测试过程中广告请求数据的校验。开发历程记录在fiddler插件开发入门级文章《教你玩转fiddler插件》中 。最近广告sdk业务,sdk从服务端获取的广告数据也被加密了。
于是,业务测试同学对插件提出了新的需求:
在fiddler中以明文形式查看服务端返回的广告数据,方便校验sdk广告处理逻辑。
fiddler中mock的广告数据,以密文形式返回给sdk(加密规则与服务端一致,保证sdk可以正确解析)。
下面简单介绍一下业务中的加密规则,方便大家理解本次需求的特殊性。示意图如下所示:
加密内容:
广告sdk广告请求数据(post数据)
服务端返回的广告数据(json形式)
加密方式:
对称加密算法AES
通过公钥体系RSA传递AES密钥
本次需求难点在于,广告请求每一次http会话中,request和response共享加密密钥,而request中才携带加密密钥,实现插件时需要考虑共享密钥方案。而对sdk广告请求进行mock,也同样需要解析请求中的AES密钥,然后利用该密钥进行加密,保证sdk可以正确解析加密数据。
response解密插件
我们首先来看一下服务端返回的response解密插件如何实现。在《教你玩转fiddler插件》 文中,我们已经实现了request的解密插件。与该方案类似,解密response需要继承Inspector2, IResponseInspector2, IBaseInspector2接口。我们需要实现response中body数据的解密逻辑。关键代码如下:
前面提到response和request共享密钥。所以,request解密插件和response解密插件必须共享密钥。我们通过全局变量实现两个插件的密钥共享。
mock数据加密插件
mock数据加密插件主要实现两个功能: 数据mock和mock文件选择。
数据mock
前面了解了request和response解密插件(继承Inspector接口),插件逻辑只有在我们选中fiddler中一个session才会执行。而mock数据,需要针对sdk发送的每个请求(http request),自动执行mock逻辑。代理服务器mock数据,实际上是在捕获请求数据后,对response中数据进行替换。所以针对该需求,我们需要实现IAutoTamper接口。我们看一下fiddler官网关于IAutoTamper接口的介绍。
Call Extension for Each Web Request
Extensions that implement the IAutoTamper interface (which extends IFiddlerExtension) are called for each HTTP/HTTPS request andresponse, enabling modifications, logging, or other operations. Warning: Functions in this interface are called on background, non-UIthreads.To update UI, use Invoke or BeginInvoke to update the UI. Also, note that the IAutoTamper::* functions may be called before theOnLoad event is called-- Fiddler allows traffic to flow before the UI is fully available.
我们实现的类继承IAutoTamper接口,fiddler每次捕获到http或者https请求都会自动执行该逻辑。
在IAutoTamper接口中,提供多种方法实现对http或者https session的修改,每个方法调用的时机都不一致。我们依据自己的需求在不同的方法中实现request或者response修改逻辑。针对我们业务中的mock需求,插件中在AutoTamperResponseBefore方法中,读取本地的mock文件,并且进行AES加密,然后替换原有的response数据。在AutoTamperResponseBefore中实现加密mock数据替换,可以使用前面的response解密插件查看明文数据(因为AutoTamperResponseBefore逻辑会在fiddler inspectors编辑session之前生效)。各个方法调用时机如下:
mock文件选择
为了方便测试过程中对mock数据文件进行更改,插件需要提供mock文件选择功能。 在IAutoTamper基础上如何实现UI操作呢?非常方便的是,IAutoTamper继承自IFiddlerExtension类,IFiddlerExtentsion在fiddler启动的时候便会调用。我们通过该类的方法实现UI控件的加载,并且在UI界面中实现文件的选择功能。
我们看一下fiddler官网关于IFiddlerExtension类的解释:
Public classes in your assembly that implement the IFiddlerExtension interface will be loaded by Fiddler during startup.
public interface IFiddlerExtension
{
// Called when Fiddler User Interface is fully available
void OnLoad();
// Called when Fiddler is shutting down
void OnBeforeUnload();
UI加载代码逻辑如下:
通过mock逻辑实现,配合ui选择mock文件,mock数据加密插件实现完成。测试同事,可以随时对服务端返回的广告response进行mock,测试sdk的功能逻辑。
思考
为何要写fiddler插件?
广告sdk发送的广告请求是业务测试的校验重点。
测试中,业务测试同事需要依据服务端返回的广告response校验sdk处理逻辑。
同时,测试过程中需要mock一些异常数据,校验sdk的健壮性。
项目团队特殊,客户端团队和服务端团队分别在不同的城市。对sdk的广告数据校验,无法直接查看服务端的数据库,只能通过抓包进行查
看。
业务测试同事习惯于fiddler抓包校验。
媒体审核人员需要在加密情况下检查广告打点结果。
基于以上几点考虑,于是开发fiddler插件,方便业务测试同事校验广告数据,并且mock数据校验sdk辑。
能否有替代方案?
我们也在思考,如果不用fiddler插件方案,我们该如何处理加密的request和response?我们该如何处理mock数据加密问题?
对于数据加密问题,如果不采用fiddler插件方案,我们可能需要在测试demo中专门增加一套不加密的接口,来测试sdk逻辑。但是这样造成的问题是,不能很好的覆盖加密和解密逻辑。
如果不采用fiddler插件,而使用其他小工具,需要手动拷贝数据到工具中,进行解密查看,严重影响测试效率。
对于mock数据加密,大家可能第一时间会考虑到使用mockserver的方案进行处理。使用mockserver虽然可以解决mock加密问题,但是并不太方便业务测试同事随时更改mock数据。
目前方案还有很多不完善或思考不全面的地方,欢迎大家讨论或给出更好的建议。
Qtest是360旗下的专业测试团队!
是WEB平台部测试技术平台化、效率化的先锋力量!
领取专属 10元无门槛券
私享最新 技术干货