Hybrid Android协议加解密分析
字数 1367 2025-08-22 12:22:24

Hybrid Android协议加解密分析教学文档

一、前言

本文档基于对Hybrid Android应用中加解密协议的分析,详细记录了从抓包分析到逆向工程的全过程。该应用采用了React Native混合开发模式,加解密逻辑主要在前端JavaScript中实现。

二、抓包分析

1. 请求包结构

POST /app/fsOrder/getAllFsOrderListByUser/ HTTP/1.1
accept: application/json
authorization: Bearer
timestamp: 1567065637961
Content-Type: application/json; charset=utf-8
Content-Length: 256
Host: xxx.com
Connection: close
User-Agent: okhttp/3.6.0

{
  "data":"WmPKAOqVK3nmj2751oQM/1fyZJ/QQIMe2itv4LufWyk87WgwkJScqu68J/IQX1Pr",
  "key":"LywemIhGqlzqDBOXOPxdY+nifhoq2lBILu2N6WUpJ/4Hrp5W4ihHO1vQuw0joHV6JiiFNzP1+j9hqp1VzmZoboHqRa411BltsuxjEmEMyIJqWK/zDKK+jBreRLH5bXCQOm4gYzHMFY6rob7aC8NhfFhc1r9hfIozhoIK2vbzIUc="
}

2. 响应包结构

HTTP/1.1 200 OK
Date: Thu, 29 Aug 2019 08:00:22 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 216
Connection: close

{
  "data":"nt4BMbi2d7oZ/bFg5mwe2w==",
  "key":"o72x8DRL62zUVojRxEsUEP5w2Aa6BXWAZqo8sAFSK9sK47YiGewIIl9LCa1OQ6JgoXn+jVUdENfPSilBBEVwyaJeFFiJ/H24/flwqV/6nVT7YXdvly5dtdXeU6b6iHdpAHtDuaTxy7YJBstNQMo+mB4F6tGvx5D4TK7zpXIMAZk="
}

3. 初步分析

  • data字段:加密的请求/响应数据
  • key字段:加密data的密钥
  • 密钥长度明显长于数据,表明使用了不同的加密算法

三、逆向分析

1. Java层分析

  1. 应用架构识别

    • MainActivity继承自ReactActivity
    • assets目录结构表明采用Hybrid开发模式
  2. 搜索关键词

    • 搜索路由getAllFsOrderListByUser无结果
    • 搜索"key"和"data"结果过多且多为第三方SDK引用
  3. 方法剖析(Method Profiling)

    • 定位到可疑函数com.loc.n.a
    • 发现疑似加解密操作但无法确定
  4. 动态调试

    • 下断点未触发,表明加解密可能不在Java层

2. JavaScript层分析

  1. 定位关键文件

    • 发现jsencrypt.jsutils.js文件
    • 全局搜索定位到加解密函数
  2. 加解密函数实现

// AES加密
function AESencrypt(text, key) {
  var result = CryptoJS.AES.encrypt(
    CryptoJS.enc.Utf8.parse(text),
    CryptoJS.enc.Utf8.parse(key),
    {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    }
  );
  return result.toString();
};

// AES解密
function AESdecrypt(text, key) {
  var result = CryptoJS.AES.decrypt(
    text,
    CryptoJS.enc.Utf8.parse(key),
    {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    }
  );
  return result.toString(CryptoJS.enc.Utf8);
};

// RSA加密
function RSAencrypt(text) {
  var rsaEn = new JSEncrypt();
  rsaEn.setPrivateKey(rsaPubKey); // 注意:使用公钥作为私钥
  var enc = rsaEn.encrypt(text);
  return enc;
};

// RSA解密
function RSAdecrypt(text) {
  var rsaDn = new JSEncrypt();
  rsaDn.setPublicKey(rsaprivateKey2); // 注意:使用私钥作为公钥
  var dec = rsaDn.decrypt(text);
  return dec;
}
  1. 加解密流程

请求加密流程

  1. 生成时间戳timeS = new Date().getTime()
  2. 构造AES密钥:key = timeS + '123sadsof313r24rsd',截取前16位
  3. 使用RSA加密AES密钥:rsaKey = RSAencrypt(key)
  4. 使用AES加密请求体:value = AESencrypt(body, key)
  5. 构造最终请求体:{data: value, key: rsaKey}

响应解密流程

  1. 使用RSA解密响应中的key字段获取AES密钥:aaPwd = RSAdecrypt(data.key)
  2. 使用AES解密data字段:aaData = AESdecrypt(data.data, aaPwd)
  3. 解析解密后的JSON数据

四、关键发现

  1. 密钥生成

    • 基于时间戳加上固定字符串
    • 截取前16位作为AES密钥
  2. RSA使用异常

    • RSAencrypt中使用公钥作为私钥
    • RSAdecrypt中使用私钥作为公钥
    • 这种用法非常规,可能是实现错误
  3. 加密模式

    • AES使用ECB模式和PKCS7填充
    • ECB模式安全性较低,建议使用CBC等更安全的模式

五、安全建议

  1. 密钥管理

    • 避免使用时间戳等可预测值作为密钥
    • 考虑使用更安全的密钥派生方式
  2. 加密算法使用

    • 避免使用ECB模式,改用CBC等更安全模式
    • 确保IV(初始化向量)随机且唯一
  3. RSA使用

    • 修正公钥/私钥使用方式
    • 考虑使用更标准的RSA加密实现
  4. 代码混淆

    • 对JavaScript代码进行混淆处理
    • 避免硬编码密钥在客户端

六、总结

该Hybrid Android应用采用了前端JavaScript实现加解密的方案:

  1. 使用AES加密业务数据
  2. 使用RSA加密AES密钥
  3. 密钥基于时间戳生成
  4. 加解密逻辑完全暴露在前端代码中

这种实现方式虽然方便,但存在多个安全隐患,建议按照上述安全建议进行改进。

Hybrid Android协议加解密分析教学文档 一、前言 本文档基于对Hybrid Android应用中加解密协议的分析,详细记录了从抓包分析到逆向工程的全过程。该应用采用了React Native混合开发模式,加解密逻辑主要在前端JavaScript中实现。 二、抓包分析 1. 请求包结构 2. 响应包结构 3. 初步分析 data 字段:加密的请求/响应数据 key 字段:加密 data 的密钥 密钥长度明显长于数据,表明使用了不同的加密算法 三、逆向分析 1. Java层分析 应用架构识别 : MainActivity继承自ReactActivity assets目录结构表明采用Hybrid开发模式 搜索关键词 : 搜索路由 getAllFsOrderListByUser 无结果 搜索"key"和"data"结果过多且多为第三方SDK引用 方法剖析(Method Profiling) : 定位到可疑函数 com.loc.n.a 发现疑似加解密操作但无法确定 动态调试 : 下断点未触发,表明加解密可能不在Java层 2. JavaScript层分析 定位关键文件 : 发现 jsencrypt.js 和 utils.js 文件 全局搜索定位到加解密函数 加解密函数实现 : 加解密流程 : 请求加密流程 : 生成时间戳 timeS = new Date().getTime() 构造AES密钥: key = timeS + '123sadsof313r24rsd' ,截取前16位 使用RSA加密AES密钥: rsaKey = RSAencrypt(key) 使用AES加密请求体: value = AESencrypt(body, key) 构造最终请求体: {data: value, key: rsaKey} 响应解密流程 : 使用RSA解密响应中的 key 字段获取AES密钥: aaPwd = RSAdecrypt(data.key) 使用AES解密 data 字段: aaData = AESdecrypt(data.data, aaPwd) 解析解密后的JSON数据 四、关键发现 密钥生成 : 基于时间戳加上固定字符串 截取前16位作为AES密钥 RSA使用异常 : RSAencrypt 中使用公钥作为私钥 RSAdecrypt 中使用私钥作为公钥 这种用法非常规,可能是实现错误 加密模式 : AES使用ECB模式和PKCS7填充 ECB模式安全性较低,建议使用CBC等更安全的模式 五、安全建议 密钥管理 : 避免使用时间戳等可预测值作为密钥 考虑使用更安全的密钥派生方式 加密算法使用 : 避免使用ECB模式,改用CBC等更安全模式 确保IV(初始化向量)随机且唯一 RSA使用 : 修正公钥/私钥使用方式 考虑使用更标准的RSA加密实现 代码混淆 : 对JavaScript代码进行混淆处理 避免硬编码密钥在客户端 六、总结 该Hybrid Android应用采用了前端JavaScript实现加解密的方案: 使用AES加密业务数据 使用RSA加密AES密钥 密钥基于时间戳生成 加解密逻辑完全暴露在前端代码中 这种实现方式虽然方便,但存在多个安全隐患,建议按照上述安全建议进行改进。