首页 > 解决方案 > 如何为 WhatsApp 的 .crypt12 格式生成页眉和页脚?

问题描述

WhatsApp 将所有消息存储在一个 sqlite 文件中,该文件首先是 zlib 压缩,然后是 AES 加密。

解密/解压缩可以很容易地完成,如下所示:

def decrypt(db_file, key_file):
    """ Function decrypt Crypt12 Database """
    try:
        with open(key_file, "rb") as fh:
            key_data = fh.read()

        key = key_data[126:]
        with open(db_file, "rb") as fh:
            db_data = fh.read()

        iv = db_data[51:67]
        aes = AES.new(key, mode=AES.MODE_GCM, nonce=iv)
        with open("msgstore.db", "wb") as fh:
            fh.write(zlib.decompress(aes.decrypt(db_data[67:-20])))

        print db_file + " decrypted, msgstore.db created."
    except Exception as e:
print "An error has ocurred decrypting the Database:", e

但是,如果您想反转该过程,则必须生成页眉、页脚和 IV。起初我以为你可以像这样从另一个已经存在的 crypt12 文件中复制它们:

def encrypt(db_file, key_file, db_cript):
    """ Function encrypt msgstore Database """
    try:
        with open(key_file, "rb") as fh:
            key_data = fh.read()

        key = key_data[126:]

        with open(db_cript, "rb") as fh:
            db_cript_data = fh.read()

        header = db_cript_data[:51]
        iv = db_cript_data[51:67]
        footer = db_cript_data[-20:]

        with open(db_file, "rb") as fh:
            data = fh.read()

        aes = AES.new(key, mode=AES.MODE_GCM, nonce=iv)
        with open("msgstore.db.crypt12", "wb") as fh:
            fh.write(header + iv + aes.encrypt(zlib.compress(data)) + footer)

        print "Encrypted msgstore.db created."
    except Exception as e:
        print "An error has ocurred encrypting the Database:", e

但情况似乎并非如此。每个文件的 .crypt12 文件页眉和页脚都不同。

示例 1 标头 hexdump:

0000000    0100    5802    ee46    bcaf    8968    d43b    bfaf    ca5d
0000010    a774    6b66    53ec    dbae    af60    a09c    3ad2    ba5e
0000020    7341    d224    22e7    55c3    c944    cf77    2c71    9c29
0000030    3a58    3798    d10f    897c    6ffa    f27a    e788    4d7b
0000040    24a7    43a0    f1d3    5f7c    5c74    d64d    58c9    21a4
0000050    771c    7fdc    2e14    ca93    0848    758a    c184    9058
0000060    b7d9    d847    604f    cadf    05a2    a678    4994    b711
0000070    2641    9170    8965    f6a7    9ff3    95a0    860d    aca1
0000080    214c    d644    faa7    ....    ....    ....    ....    ....

示例 2 标头 hexdump:

0000000    0100    5802    ee46    bcaf    8968    d43b    bfaf    ca5d
0000010    a774    6b66    53ec    dbae    af60    a09c    3ad2    ba5e
0000020    7341    d224    22e7    55c3    c944    cf77    2c71    9c29
0000030    3a58    1898    1435    4cc9    bdbf    e506    f138    41a6
0000040    32a0    71c5    faa9    2499    36f7    d2be    d7a8    bf28
0000050    f3ea    1571    ed80    da14    addb    63b6    1d8e    2de5
0000060    0a9c    bc31    8d86    cb42    b4ce    b603    af7c    c295
0000070    d67f    b787    1ad8    eb69    3180    1c9d    8106    1f98
0000080    e880    edd5    c285    ....    ....    ....    ....    ....

您可以看到前 25 个字节总是相等的,但其余的则完全不同。最后 16 个字节是 IV(随机数)顺便说一句。

对于页脚,您可以看到最后两个字节相等,其余字节完全不同。

示例 1 页脚 hexdump:

1464cd0    ....    2feb    12d8    a2bc    92bd    ca30    a99f    621c
1464ce0    9e87    88df    dc82    f7ea    2cfd    3e0b    ecd4    03b1
1464cf0    7720    8d3d    2dcb    382d    0031

示例 2 页脚 hexdump:

1474330    ....    d4e9    80de    d0e8    9786    4fd3    8bf2    957c
1474340    fdf5    2e24    c4f2    1b55    121a    4410    014d    c516
1474350    7531    7f0a    2d71    382d    0031

那么我如何生成这些呢?

标签: pythonencryptionaeswhatsappcrypt12

解决方案


Chat-App Decryption Key Extraction Through Information Flow Analysis一文分析了crypt12格式:

67 字节标头

  • 密码头前导码(2 字节):0x0、0x1;
  • 密钥版本(1 字节):0x2;
  • 服务器盐(32 字节):来自 WhatsApp 服务器的存储伪随机盐;
  • Google 帐户名 salt(16 个字节):用于生成 Google 帐户名哈希的 salt,将发送到 WhatsApp 服务器(更多内容见下文);
  • IV(16字节):初始化向量值。

20 字节预告片

  • MD5哈希值(16字节):加密后的数据库文件的MD5哈希值;
  • 电话号码后缀(4 个字节):由设备电话号码的最后几位数字衍生而来。

我无法重建 16 字节的 MD5 哈希,所以我想知道这些信息是否正确。也许有一些填充。


推荐阅读