You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android日志密码混淆:String.replaceAll在部分设备上失效

解决方案:Android日志中混淆明文密码

针对你遇到的这个需求——在调试日志里自动掩盖API请求中的明文密码,我整理了一套可靠的实现方案,既能处理普通JSON结构,也能覆盖嵌套的对象和数组,确保所有敏感密码都不会泄露在日志中。

核心思路

  1. 预先定义所有需要混淆的密码字段名(比如password、pwd这类常见字段)
  2. 递归解析JSON结构,遍历所有层级的字段内容
  3. 匹配到目标字段后,将明文替换为混淆字符串(比如***)
  4. 兼容JSONObject和JSONArray两种格式,非合法JSON直接返回原内容避免日志报错

完整代码实现

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class LogUtils {
    // 可自定义:添加所有需要混淆的密码相关字段名
    private static final String[] PASSWORD_FIELDS = {"password", "pwd", "login_pwd", "user_password"};

    /**
     * 混淆JSON字符串中的所有明文密码字段
     * @param jsonStr 原始JSON请求字符串
     * @return 混淆后的安全字符串
     */
    public static String obfuscatePasswordInJson(String jsonStr) {
        try {
            // 先尝试解析为JSONObject
            JSONObject jsonObject = new JSONObject(jsonStr);
            obfuscatePasswordFields(jsonObject);
            return jsonObject.toString();
        } catch (JSONException e) {
            try {
                // 如果是JSONArray格式
                JSONArray jsonArray = new JSONArray(jsonStr);
                obfuscatePasswordInArray(jsonArray);
                return jsonArray.toString();
            } catch (JSONException ex) {
                // 不是合法JSON,直接返回原字符串
                return jsonStr;
            }
        }
    }

    // 处理JSONObject中的密码字段
    private static void obfuscatePasswordFields(JSONObject jsonObject) throws JSONException {
        // 替换当前层级的密码字段
        for (String field : PASSWORD_FIELDS) {
            if (jsonObject.has(field)) {
                jsonObject.put(field, "***");
            }
        }
        // 递归处理嵌套的JSONObject或JSONArray
        for (String key : jsonObject.keySet()) {
            Object value = jsonObject.get(key);
            if (value instanceof JSONObject) {
                obfuscatePasswordFields((JSONObject) value);
            } else if (value instanceof JSONArray) {
                obfuscatePasswordInArray((JSONArray) value);
            }
        }
    }

    // 处理JSONArray中的密码字段
    private static void obfuscatePasswordInArray(JSONArray jsonArray) throws JSONException {
        for (int i = 0; i < jsonArray.length(); i++) {
            Object item = jsonArray.get(i);
            if (item instanceof JSONObject) {
                obfuscatePasswordFields((JSONObject) item);
            } else if (item instanceof JSONArray) {
                obfuscatePasswordInArray((JSONArray) item);
            }
        }
    }

    // 可选:自定义混淆规则(比如保留前2位,其余替换为***)
    private static String customMaskPassword(String rawPassword) {
        if (rawPassword == null || rawPassword.length() <= 2) {
            return "***";
        }
        return rawPassword.substring(0, 2) + "***";
    }
}

使用示例

在你输出请求日志的地方,只需要把原始JSON字符串传入工具方法即可:

// 假设你的请求JSON字符串是requestJson
String safeLogContent = LogUtils.obfuscatePasswordInJson(requestJson);
// 输出混淆后的安全日志
Log.d("AppDebug", "API Request: " + safeLogContent);

额外建议

  • 如果你使用第三方日志框架(比如Timber),可以把这个混淆逻辑集成到自定义日志树里,这样所有包含JSON的日志都会自动处理,不用每次手动调用
  • 根据对接API的实际字段名,更新PASSWORD_FIELDS数组,确保不会遗漏任何密码字段
  • 如果需要更灵活的混淆规则,比如保留部分字符,可以替换代码中的"***"为customMaskPassword(jsonObject.getString(field)),使用自定义的混淆方法

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:26:57