针对sarasa-shuffle.woff2加密字体进行解密
阅读原文时间:2023年08月12日阅读:5

本文针对的是类似于sarasa-shuffle.woff2加密字体的一个研究。

字体加密是使用Unicode编码将其映射到不同的字体显示的一种前端显示加密手段。在反爬虫中能够起到较好的效果,爬虫将只能得到sarasa字体的乱码文本。本文将以sarasa-shuffle.woff2字体为例讲解如何破解这种类型的加密字体。

1、sarasa-shuffle.woff2字体

可以使用FontCreator软件查看该字体:

字体的构成有三个部分:camp code、Unicode码以及字体本身。

比如图中这个的Unicode是62CE,campcode是25294,这些是在sarasa-shuffle.woff2定义的。我将这个字体通过OCR代码转换,得到这样的两组对应关系:

{
  ...
  "25285": "绚",
  "25292": "剑",
  "25293": "骑",
  "25294": "母",
  ...
}


{
  ...
  "uni62CD": "骑",
  "uni62CE": "母",
  "uni62D0": "羊",
  "uni62D2": "者",
  ...
}

2、将乱码句子使用上述对应关系进行转义

下面这段代码可以用来翻译一段sarasa-shuffle加密的句子,将其翻译成非'乱码'形式的字体,Windows常用对应字体。这样就可以得到一组人眼可以分辨的正常文本。

def convert2normal(encode_str):
    ret = ''
    for ch in encode_str:
        str_res_key = ch.encode("unicode_escape").decode().strip("\\u")
        try:
            value = cmap_code_word["uni" + str_res_key.upper()]
        except KeyError as e:
            value = ch
        ret = ret + value
    return ret

3、遇到类似的加密字体解决流程

使用下面这段代码去OCR识别这种字体,OCR工具是ddddocr,国内开源的一个库,识别率还可以。

def identify_word(_ttf_path):
    """识别ttf字体结果"""
    font = TTFont(_ttf_path)
    ocr = ddddocr.DdddOcr()
    dict_data1 = {}
    dict_data2 = {}
    for cmap_code, glyph_name in font.getBestCmap().items():
        bytes_io = BytesIO()
        pil = font_to_img(cmap_code, _ttf_path)
        pil.save(bytes_io, format="PNG")
        word = ocr.classification(bytes_io.getvalue())  # 识别字体
        dict_data1[glyph_name] = word
        dict_data2[str(cmap_code)] = word
        # print(cmap_code, glyph_name, word)
        # with open(f"./img/{cmap_code}_{glyph_name}.png", "wb") as f:
        #     f.write(bytes_io.getvalue())
    # 将打印出来的字典数据直接粘贴到一个新的文件中,使用"替换' ——CmapCode2word.json和GlyphName2word.json文件生成的方式
    print(dict_data1)
    print(dict_data2)

注意,务必使用print的方式将对应关系打印出来,再粘贴到文件中,直接文件写会出编码问题。

项目代码和编码文字对应关系已经开源在github上,https://github.com/flowerlake/sarasa-deshuffle