Charles二次开发-接口解密

news2024/10/6 16:28:01

1,使用背景

最近工作中对公司接口进行抓包,发现接口路径和返回都是经过加密的,对于查看接口路径及接口返回结果带来了不便,于是想到了对Charles进行小改造,在Charles上增加一个按钮对加密的请求、响应结果解密,本质是执行一个Java方法,然后将解密结果通过文本框显示出来,效果如下

解密前:

点击解密:

解密后:

2,相关环境

Charles版本:4.6.2,界面是基于JDK11版本开发的

JDK版本:所以一定要用jdk11,不然会有坑

3,开发过程

3.1,新建普通工程Custom-Decrypt,引入Charles.jar

3.2,新建CustomDecrypt类,TransactionViewerPopupMenu类,代码如下

CustomDecrypt类中decrypt方法是解密方法,根据需要编写,代码注重实现可能有点low

package com.xk72.charles.gui.transaction.actions;

import com.xk72.charles.model.Transaction;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.spec.KeySpec;
import java.util.logging.Logger;

/**
 * @author: create by libin
 * @date:2023/4/9
 */
public class CustomDecrypt extends AbstractAction {
    public final Transaction transaction;
    private static final Logger logger = Logger.getLogger("CustomDecryptLog");

    public CustomDecrypt(Transaction transaction) {
        super("CustomDecrypt");
        this.transaction = transaction;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        String requestString = transaction.getDecodedRequestBodyAsString();
        String responseString = transaction.getDecodedResponseBodyAsString();
        logger.warning("__________________________________");
        logger.info("request" + requestString);
        logger.info("response" + responseString);
        logger.warning("__________________________________");
        try {
            String request;
            if (requestString == null || requestString.length() < 1) {
                request = "空";
            } else {
                request = decrypt(requestString, DES_REQUEST_KEY);
            }
            String respnse;
            if (responseString == null || responseString.length() < 1) {
                respnse = "空";
            } else {
                respnse = decrypt(responseString, DES_RESPONSE_KEY);
            }
            String method = transaction.getMethod();
            String host = transaction.getHost() + ":" + transaction.getPort();
            String path = transaction.getPath();
            String file = transaction.getFile();
            String query = transaction.getQuery();
            String content = "method:" + method + "\n" +
                    "host:" + host + "\n" +
                    "path:" + path + "\n" +
                    "file:" + file + "\n" +
                    "query:" + query + "\n";
            if ("GET".equals(method)) {
                String url = host + file;
                content += "url:" + url + "\n";
            }
    

            WaringDialog("request", content);
            WaringDialog("response", respnse);
        } catch (Exception e) {
            logger.warning("CustomDecrypt Exception" + e.getMessage());
        }
    }




    public static void WaringDialog(String title, String content) {

        JFrame JFrame = new JFrame(title);
        JFrame.setPreferredSize(new Dimension(800, 500));
        JTextArea textArea = new JTextArea();
        textArea.setText(content + "\n");
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);

        JScrollPane jScrollPane = new JScrollPane(textArea);
        jScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        jScrollPane.setAutoscrolls(false);
        JFrame.setContentPane(jScrollPane);
        JFrame.pack();
        JFrame.setVisible(true);
    }


    @Override
    public boolean accept(Object sender) {
        return false;
    }
}

 TransactionViewerPopupMenu类,通过jd-gui反编译得到,反编译后有错误将.换成$符号即可

package com.xk72.charles.gui.transaction.popups;

import com.xk72.charles.gui.session.popups.TransactionPopupMenu;
import com.xk72.charles.gui.transaction.actions.Base64DecodeAction$Text;
import com.xk72.charles.gui.transaction.actions.Base64DecodeAction$TextComponent;
import com.xk72.charles.gui.transaction.actions.CopyToClipboardAction$Text;
import com.xk72.charles.gui.transaction.actions.CopyToClipboardAction$TextComponent;
import com.xk72.charles.gui.transaction.actions.CustomDecrypt;
import com.xk72.charles.model.Transaction;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.MouseEvent;

public class TransactionViewerPopupMenu extends TransactionPopupMenu {
    // 定义 Transaction
    private final Transaction transaction;

    public TransactionViewerPopupMenu(Transaction paramTransaction) {
        super(paramTransaction, null, null, null);
        // 接收
        this.transaction = paramTransaction;
    }

    @Override
    protected void prepare(MouseEvent paramMouseEvent) {
        Component component = (Component)paramMouseEvent.getSource();
        if (component instanceof JTable) {
            JTable jTable = (JTable)component;
            Point point = paramMouseEvent.getPoint();
            int i = jTable.rowAtPoint(point);
            int j = jTable.columnAtPoint(point);
            if (i >= 0 && j >= 0) {
                Object object = jTable.getValueAt(i, j);
                if (object != null) {
                    add((Action)new CopyToClipboardAction$Text(object.toString()));
                    if (object instanceof String)
                        add((Action)new Base64DecodeAction$Text((String)object, component));
                    addSeparator();
                }
            }
        } else if (component instanceof JTextComponent) {
            add((Action)new CopyToClipboardAction$TextComponent((JTextComponent)component));
            add((Action)new Base64DecodeAction$TextComponent((JTextComponent)component));
            // 新增一个按钮,执行按钮的时候会调用CustomDecrypt的actionPerformed方法
            add((Action)new CustomDecrypt(this.transaction));
            addSeparator();
        }
        prepare(false);
    }
}

3.3,将上面的CustomDecrypt类和TransactionViewerPopupMenu类,编译成class 

 3.4,执行命令前进入到out\production\custom-decrypt路径

执行如下命令,意思是将这两个类的class加到charles.java包里面

jar -uvf H:\learn\custom-decrypt\libs\charles.jar com\xk72\charles\gui\transaction\actions\CustomDecrypt.class

jar -uvf H:\learn\custom-decrypt\libs\charles.jar com\xk72\charles\gui\transaction\popups\TransactionViewerPopupMenu.class

 出现正在添加,表示执行成功 

3.5,将项目中libs下的charles.jar替换到charles的安装路径下的lib目录,例如:D:\charles\location\lib

4,测试

替换后,打开charles软件,例如编写一个测试接口(根据需要自己编写),抓包如下

点击按钮后

 结语:以上笔记已经非常详细,主要给自己做个记录,然后也能分享一下技术,整体来看需要花点时间,如果有问题,不负责任,仅供参考,毕竟能做程序员的都不笨,别跟个别人一样白嫖了文章,自己不会还要骂人,我真是擦了尼玛

参考了以下文章:charles 增加 自定义解密功能 · TesterHome

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[学习笔记]计算机图形学(一)

计算机图形学学习笔记&#xff08;一&#xff09; 什么是计算机图形学 计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。 什么是好的画面&#xff1f; 从技术层面简单的评判标准&#xff1a;直接看画面…

Android实现RecyclerView分组显示功能完整示例(自定义组头和Item布局)

实现效果截图&#xff1a; 首先&#xff0c;我们需要为RecyclerView添加一个分组的概念&#xff0c;我们可以创建一个Group类来表示分组&#xff0c;包括分组名称和分组中的数据项列表。代码如下&#xff1a; public class Group {private String name;private List<Item&g…

ChatGPT-5到底有多强?Battle!咱貌似也不输呀!

盘点今年的热点话题&#xff0c;ChatGPT是不可避免要被反复提及的一part。从去年的-3.0到今年的-3.5&#xff0c;再到上月刚发布-4.0。从用户体验和市场反馈来讲&#xff0c;这半年的时间&#xff0c;ChatGPT每一步都走得又稳又快&#xff01; 回想起今年2月初ChatGPT全网爆火的…

最短路径-dijkstra/floyd

目录 floyd -dijkstra floyd floyd:用来求所有顶点之间的最短路径问题,求最短路径具体节点顺序&#xff0c;求各点之间最短路径长度 理解floyd&#xff1a; 二维矩阵图&#xff0c;就是不断通过测试新的节点k&#xff0c;看看k节点能不能作为中间节点优化各点之间的最短距离…

SourceMap源码映射详细讲解

SourceMap源码映射详细讲解 前端工程打包后代码会跟项目源码不一致&#xff0c;当代码运行出错时控制台上定位出错代码的位置跟项目源码上不对应。这时候我们很难定位错误代码的位置。SourceMap的用途是可以将转换后的代码映射回源码&#xff0c;如果设置了js文件对应的map资源…

Java每日一练(20230416)

目录 1. 三数之和 &#x1f31f;&#x1f31f; 2. 基本计算器 &#x1f31f;&#x1f31f;&#x1f31f; 3. 通配符匹配 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java…

Android:编译libevent动态库并移植jni中,在Android AVD虚拟机上实现一个http服务器

libevent源码&#xff1a;libevent-2.1.8-stable Android Studio版本&#xff1a;Android Studio Electric Eel | 2022.1.1 Patch 2 AVD虚拟机为x86. https://developer.android.google.cn/studio/run/emulator-networking?hlzh-cn#connecting 大体步骤&#xff1a; 1.在ws…

Vue2_01_data_插值

插值语法 {{name}} data: vue实例的数据对象 data中数据变化时将重新渲染容器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!--引入vue,引入之后vue.js 创建了一个全局变…

c语言进阶篇_动态内存管理(数组可以自动扩容?)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解c语言中的动态内存管理知识,涉及malloc函数、call…

微信小程序运行及更新机制

微信小程序运行及更新机制1、微信小程序运行机制1.1 前台和后台1.2 小程序启动&#xff1a;冷启动和热启动1.3 小程序销毁2、微信小程序更新机制2.1 启动时同步更新定期检查发现版本更新用户长时间未使用小程序2.2 启动时异步更新开发者手动触发更新2.3 小程序管理后台的相关设…

软件测试分类详解

一图看清软件测试分类 一、按测试技术分&#xff08;是否查看代码&#xff09; **1. 黑盒测试**&#xff1a;软件功能是否正常使用【功能的测试】 **2. 白盒测试**&#xff1a;代码逻辑是否正确【结构的测试】 **3. 灰盒测试**&#xff1a;介于两者之间的测试&#xff0c;也…

第12章_集合框架

第12章_集合框架 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 集合框架概述 1.1 生活中的容器 1.2 数组的特点与弊端 一方面&#xff0c;面向对象语言对事物的体现都是以对…

iOS 项目嵌入Flutter 运行

一 创建Flutter 模块命令行flutter create --template module my_flutter创建完成后&#xff0c;该模块和普通的Flutter项目一直&#xff0c;可以通过Android Studio或VSCode打开、开发、运行&#xff1b;和之前项目不同的iOS和Android项目是一个隐藏文件&#xff0c;并且我们…

黑马点评缓存练习题shop-type缓存,附带详细解析

黑马点评缓存练习题shop-type缓存 依照shop详情的缓存 Controller代码 public class ShopTypeController {Resourceprivate IShopTypeService typeService;GetMapping("list")public Result queryTypeList() {return typeService.queryList();} }创建service接口方…

SentenceTransformers介绍

SentenceTransformer使用范例 1使用SentenceTransformers获得句子向量嵌入 from sentence_transformers import SentenceTransformer#模型下载 model SentenceTransformer(paraphrase-MiniLM-L6-v2)# 编码句子 sentences [Python is an interpreted high-level general-pur…

JavaScript【五】JavaScript中的对象

文章目录&#x1f31f;前言&#x1f31f;对象&#xff1a;&#x1f31f;声明对象&#xff1a;&#x1f31f;隐式创建对象&#xff1a;&#x1f31f;实例化Object&#xff1a;&#x1f31f;实例化自定义构造函数&#xff1a;(会重复占用内存)&#x1f31f;new运算符具体做了什么…

自动内存管理之【常量池】

首先上一段代码&#xff0c;一起思考&#xff0c;打印的结果&#xff0c;基于jdk1.8。 StringBuilder sbnew StringBuilder("我爱我媳妇儿");String s sb.toString();System.out.println(s.intern()s); //falsesb.append("&#xff0c;她也很爱我&#xff01;&…

C++——入门讲解

作者&#xff1a;几冬雪来 时间&#xff1a;2023年4月16日 内容&#xff1a;C入门讲解 目录 前言&#xff1a; 1.什么是C&#xff1a; 2.C关键字&#xff1a; 3.命名冲突&#xff1a; 4.域和::操作符&#xff1a; 5.std内容讲解&#xff1a; 6.<<符&#xff1a…

STM32F4_独立看门狗详解(IWDG)

目录 1. 独立看门狗是什么 2. 独立看门狗 IWDG简介 3. 独立看门狗的主要特性 4. 独立看门狗功能 4.1 独立看门狗功能框图 4.2 IWDG寄存器 4.2.1 关键字寄存器 IWDG_KR 4.2.2 预分频器寄存器 IWDG_PR 4.2.3 重载寄存器 IWDG_RLR 4.2.4 状态寄存器 IWDG_SR 5. 库函数…

OpenCV实战之人脸美颜美型(六)——磨皮

1.需求分析 有个词叫做“肤若凝脂”,直译为皮肤像凝固的油脂,形容皮肤洁白且光润,这是对美女的一种通用评价。实际生活中我们的皮肤多少会有一些毛孔、斑点等表现,在观感上与上述的“光润感”相反,因此磨皮也成为美颜算法中的一项基础且重要的功能。让皮肤变得更加光润,就…