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

如何用PDFBox 2.0.29检测PDF自定义编码及混淆

判断PDF是否使用自定义编码及混淆识别(基于PDFBox 2.0.29)

一、自定义编码判断:现有方案的问题与优化思路

你当前通过判断字体名称是否为null来识别自定义编码的方案并不准确,字体名称为空不等同于使用了自定义编码。正确的判断逻辑应聚焦字体的编码类型:

PDF标准编码(如WinAnsiEncoding、MacRomanEncoding、StandardEncoding等)是预定义的,自定义编码通常以自定义Encoding字典、非标准CMap或异常ToUnicode映射的形式存在。

基于PDFBox 2.0.29的优化实现示例:

boolean hasUserDefinedEncoding = false;
if (document.getNumberOfPages() > 0) {
    PDPage page = document.getPage(0);
    PDResources res = page.getResources();
    for (COSName fontName : res.getFontNames()) {
        PDFont font = res.getFont(fontName);
        // 1. 校验编码是否为PDF标准编码类型
        Encoding encoding = font.getEncoding();
        if (!(encoding instanceof WinAnsiEncoding 
              || encoding instanceof MacRomanEncoding 
              || encoding instanceof StandardEncoding 
              || encoding instanceof PDFDocEncoding)) {
            hasUserDefinedEncoding = true;
            break;
        }
        // 2. 检查是否存在自定义ToUnicode映射(常伴随编码混淆)
        COSBase toUnicode = font.getCOSObject().getDictionaryObject(COSName.TO_UNICODE);
        if (toUnicode != null && toUnicode instanceof COSStream) {
            hasUserDefinedEncoding = true;
            break;
        }
    }
}

关键判断点:

  • 直接校验字体编码实例是否属于标准编码类型
  • 检查是否存在自定义ToUnicode流(这类流常用于自定义字符映射或混淆)

二、TargetStream StreamEDS混淆PDF的识别方法

针对TargetStream StreamEDS生成的带混淆选项的PDF,可通过以下特征识别:

  1. 文本复制异常:复制到记事本的内容出现大量替换字符(如>、%、_替代正常字母),属于典型的字符映射混淆表现
  2. PDFBox解析乱码:解析结果出现不可读的控制字符或乱码(如]ÍËUÈ:%ÑÄÇ),说明字体的字符编码映射被篡改
  3. 字体资源特征:字体存在异常Encoding字典、无标准名称的自定义字体,或ToUnicode流内容混乱(无法映射到正常Unicode字符)

补充实现思路:
提取字体的ToUnicode流内容,若映射规则无规律、无法对应正常字符范围,即可判定为混淆PDF。示例代码片段:

// 检查单字体的ToUnicode映射是否异常
COSBase toUnicode = font.getCOSObject().getDictionaryObject(COSName.TO_UNICODE);
if (toUnicode instanceof COSStream) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(((COSStream) toUnicode).createInputStream()))) {
        String line;
        boolean hasAbnormalMapping = false;
        while ((line = reader.readLine()) != null) {
            // 简单判断:若出现大量无意义的字符映射,或映射范围不符合常规文本
            if (line.matches(".*\\d+\\s+<[0-9A-Fa-f]{2,4}>.*") && line.length() > 50) {
                hasAbnormalMapping = true;
                break;
            }
        }
        if (hasAbnormalMapping) {
            // 判定为混淆或自定义编码场景
        }
    } catch (IOException e) {
        // 处理流读取异常
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 04:25:16