Mobile Debug解密功能默认支持DES/3DES/AES/RSA,如果您调试的接口涉及其他加密算法或者混合算法,那么这边文章可以带您了解Mobile Debug代理数据解密的http-api解密规范。
Mobile Debug代理数据解密的http-api解密原理是什么?
当您点击代理列表数据查看详情时,若您配置了http-api解密规则,Mobile Debug会将当前代理数据详情通过POST请求发送到您填写的URL地址,该URL地址返回的响应正文将显示在原先密文位置;

Mobile Debug解密数据POST了哪些信息?
POST数据提交了1个标准的JSON数据包,包含了以下字段:
{
/**是否是来自解密RequestBody的请求,如果为false则为解密ResponseBody*/
isRequest : false,
/**请求正文的原始流数据的base64编码文本(如果有)*/
requestBodyBase64 : null,
/**请求正文的字符编码对应的代码页标识符(CodePage),如果不存在请求正文则该值为0*/
requestBodyEncoding : 0,
/**请求原始header头*/
requestHeaders : "Host: 192.168.1....",
/**请求端的ip地址和端口信息*/
requestIpAddress : "192.168.1.8:51319",
/**请求类型 GET POST PUT等*/
requestMethod : "GET",
/**请求发起时间对应的格式化字符串*/
requestTime : "/Date(1562566069915+0800)/",
/**响应正文的原始流数据的base64编码文本(如果有)*/
responseBodyBase64 : "SGVsbG8gV29ybGQ=",
/**响应正文的字符编码对应的代码页标识符(CodePage),如果不存在响应正文则该值为0*/
responseBodyEncoding : 65001,
/**响应原始headers*/
responseHeaders : "Cache-Control: private\r\nContent-Type: text/plain",
/**响应端的ip地址和端口信息*/
responseIpAddress : "192.168.1.92:80",
/**服务端响应状态码*/
responseStatus : "200",
/**收到响应时间对应的格式化字符串*/
responseTime : "/Date(1562566069926+0800)/",
/**请求URL*/
url : "http://192.168.1.92/test/decode/response-http-api.ashx"
}API接口返回值有何要求?
响应状态码必须为200,正文信息将会展示在Mobile Debug的界面中,如果返回值为标准的JSON,则默认会自动进行解析展示。
为什么是HTTP-API而不走插件?
插件需要将代码部署在Mobile Debug程序中,而HTTP协议是个网络传输协议标准,之所以采取http-api的方式处理解密主要考虑到以下因素:
1.密钥信息的安全性问题;http解密只需由api接口人员编写一套代码部署在内网服务器中,无需将具体代码下发到开发和测试人员,降低了密钥泄露的风险。
2.通用性,http协议是个广泛通用的网络传输协议,这意味着服务端实现无需和Mobile Debug的开发语言保持一致,nodejs,C#,PHP,Java等,降低了开发人员编写解密API的学习成本。
3.独立性;保证了Mobile Debug程序的稳定性。
以下是部分语言读取JSON的demo:
C#
<%@ WebHandler Language="C#" Class="http_api_c_sharp" %>
using System;
using System.Web;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
public class http_api_c_sharp : IHttpHandler {
public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "text/plain";
var httpMethod = context.Request.HttpMethod;
if (httpMethod != "POST") {
context.Response.StatusCode = 500;
context.Response.Write("不支持的提交方式:" + httpMethod);
context.Response.End();
return;
}
var contentLength = context.Request.ContentLength;
if (contentLength < 1) {
context.Response.StatusCode = 500;
context.Response.Write("请求正文为空");
context.Response.End();
return;
}
byte[] data = new byte[contentLength];
using (var reader = context.Request.InputStream) {
reader.Read(data, 0, contentLength);
}
var value = context.Request.ContentEncoding.GetString(data);
var proxyData = JSON.parse<MobileDebugProxyData>(value);
context.Response.Write(JSON.stringify(proxyData));
}
public bool IsReusable {
get {
return false;
}
}
/// <summary>
/// Mobile Debug代理数据信息
/// </summary>
[DataContract(Namespace = "http://www.mobiledebug.com/")] public class MobileDebugProxyData {
/// <summary>
/// 是否是来自解密RequestBody的请求,如果为false则为解密ResponseBody
/// </summary>
/// <returns></returns>
[DataMember(Name = "isRequest")] public bool IsRequest { get; set; }
/// <summary>
/// 请求URL
/// </summary>
/// <returns></returns>
[DataMember(Name = "url")] public string Url { get; set; }
/// <summary>
/// 请求类型 GET POST PUT等
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestMethod")] public string RequestMethod { get; set; }
/// <summary>
/// 请求原始header头
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestHeaders")] public string RequestHeaders { get; set; }
/// <summary>
/// 请求正文的字符编码对应的代码页标识符(CodePage),如果不存在请求正文则该值为0
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestBodyEncoding")] public int RequestBodyEncoding { get; set; }
/// <summary>
/// 请求正文的原始流数据的base64编码文本(如果有)
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestBodyBase64")] public string RequestBodyBase64 { get; set; }
/// <summary>
/// 请求发起时间
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestTime")] public DateTime RequestTime { get; set; }
/// <summary>
/// 请求端IP地址和端口号
/// </summary>
/// <returns></returns>
[DataMember(Name = "requestIpAddress")] public string RequestIpAddress { get; set; }
/// <summary>
/// 响应状态码
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseStatus")] public string ResponseStatus { get; set; }
/// <summary>
/// 响应headers
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseHeaders")] public string ResponseHeaders { get; set; }
/// <summary>
/// 请求正文的流数据的base64编码文本(如果有)
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseBodyBase64")] public string ResponseBodyBase64 { get; set; }
/// <summary>
/// 响应正文的字符编码对应的代码页标识符(CodePage),如果不存在响应正文则该值为0
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseBodyEncoding")] public int ResponseBodyEncoding { get; set; }
/// <summary>
/// 响应返回时间
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseTime")] public DateTime ResponseTime { get; set; }
/// <summary>
/// 响应端IP地址和端口号
/// </summary>
/// <returns></returns>
[DataMember(Name = "responseIpAddress")] public string ResponseIpAddress { get; set; }
}
/// <summary>
/// 解析JSON
/// </summary>
public static class JSON {
/// <summary>
/// 将字符串序列化为指定的对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonString"></param>
/// <returns></returns>
/// <remarks></remarks>
public static T parse<T>(string jsonString) {
if (string.IsNullOrEmpty(jsonString)) return default(T);
try {
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))){
var type1 = typeof(T);
var data = new DataContractJsonSerializer(type1);
var obj = (T)data.ReadObject(ms);
return obj;
}
}
catch {
return default(T);
}
}
/// <summary>
/// 将对象序列化成字符串
/// </summary>
/// <param name="jsonObject"></param>
/// <returns></returns>
/// <remarks></remarks>
public static string stringify(Object jsonObject ) {
try {
using (var ms = new MemoryStream()) {
var d = new DataContractJsonSerializer(jsonObject.GetType());
d.WriteObject(ms, jsonObject);
return Encoding.UTF8.GetString(ms.ToArray());
}}
catch {
return null;
}
}
}
}VB.NET
<%@ WebHandler Language="VB" Class="http_api" %>
Imports System
Imports System.Web
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.IO
Imports System.Text
Public Class http_api : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/plain"
Dim httpMethod = context.Request.HttpMethod
If httpMethod <> "POST" Then
context.Response.StatusCode = 500
context.Response.Write("不支持的提交方式:" & httpMethod)
context.Response.End()
Return
End If
Dim contentLength = context.Request.ContentLength
If contentLength < 1 Then
context.Response.StatusCode = 500
context.Response.Write("请求正文为空")
context.Response.End()
Return
End If
Dim data = New Byte(contentLength - 1) {}
Using reader = context.Request.InputStream
reader.Read(data, 0, contentLength)
End Using
Dim value = context.Request.ContentEncoding.GetString(data)
Dim proxyData = JSON.parse(Of MobileDebugProxyData)(value)
context.Response.Write(JSON.stringify(proxyData))
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
''' <summary>
''' Mobile Debug代理数据信息
''' </summary>
<DataContract(Namespace:="http://www.mobiledebug.com/")> Public Class MobileDebugProxyData
''' <summary>
''' 是否是来自解密RequestBody的请求,如果为false则为解密ResponseBody
''' </summary>
''' <returns></returns>
<DataMember(Name:="isRequest")> Public Property IsRequest As Boolean
''' <summary>
''' 请求URL
''' </summary>
''' <returns></returns>
<DataMember(Name:="url")> Public Property Url As String
''' <summary>
''' 请求类型 GET POST PUT等
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestMethod")> Public Property RequestMethod As String
''' <summary>
''' 请求原始header头
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestHeaders")> Public Property RequestHeaders As String
''' <summary>
''' 请求正文的字符编码对应的代码页标识符(CodePage),如果不存在请求正文则该值为0
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestBodyEncoding")> Public Property RequestBodyEncoding As Integer
''' <summary>
''' 请求正文的原始流数据的base64编码文本(如果有)
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestBodyBase64")> Public Property RequestBodyBase64 As String
''' <summary>
''' 请求发起时间
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestTime")> Public Property RequestTime As DateTime
''' <summary>
''' 请求端IP地址和端口号
''' </summary>
''' <returns></returns>
<DataMember(Name:="requestIpAddress")> Public Property RequestIpAddress As String
''' <summary>
''' 响应状态码
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseStatus")> Public Property ResponseStatus As String
''' <summary>
''' 响应headers
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseHeaders")> Public Property ResponseHeaders As String
''' <summary>
''' 请求正文的流数据的base64编码文本(如果有)
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseBodyBase64")> Public Property ResponseBodyBase64 As String
''' <summary>
''' 响应正文的字符编码对应的代码页标识符(CodePage),如果不存在响应正文则该值为0
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseBodyEncoding")> Public Property ResponseBodyEncoding As Integer
''' <summary>
''' 响应返回时间
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseTime")> Public Property ResponseTime As DateTime
''' <summary>
''' 响应端IP地址和端口号
''' </summary>
''' <returns></returns>
<DataMember(Name:="responseIpAddress")> Public Property ResponseIpAddress As String
End Class
''' <summary>
''' 解析JSON
''' </summary>
Public Class JSON
Private Sub New()
End Sub
''' <summary>
''' 将字符串序列化为指定的对象
''' </summary>
''' <typeparam name="T"></typeparam>
''' <param name="jsonString"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function parse(Of T)(jsonString As String) As T
If String.IsNullOrEmpty(jsonString) Then
Return Nothing
End If
Try
Using ms = New MemoryStream(Encoding.UTF8.GetBytes(jsonString))
Dim type1 = GetType(T)
Dim data = New DataContractJsonSerializer(type1)
Dim obj As T = data.ReadObject(ms)
Return obj
End Using
Catch
Return Nothing
End Try
End Function
''' <summary>
''' 将对象序列化成字符串
''' </summary>
''' <param name="jsonObject"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function stringify(jsonObject As Object) As String
Try
Using ms = New MemoryStream()
Dim d = New DataContractJsonSerializer(jsonObject.GetType())
d.WriteObject(ms, jsonObject)
Return Encoding.UTF8.GetString(ms.ToArray())
End Using
Catch
Return Nothing
End Try
End Function
End Class
End ClassNodeJS (node server.js)
//server.js
var http = require("http");
http.createServer((req,res)=>{
res.writeHead(200,{'Content-Type':'text/plain;charset=utf-8'});
if(req.method!=="POST"){
res.write("不支持的Method:"+req.method);
res.end();
return;
}
req.on("data",(chunk)=>{
let data=chunk.toString();
try{
proxyData = JSON.parse(data);
}catch(ex){
proxyData=null;
}
if(proxyData===null){
res.write("数据接收异常");
res.end();
return;
}
res.write("客户端提交的信息为:" + JSON.stringify(proxyData));
res.end();
});
}).listen(8920);