跳转至

腾讯云httpdns

下面给出 加密 代码,同样遵循腾讯云 HTTPDNS 官方文档中的约定:

  1. AES-CBC-PKCS7(16 B 随机 IV 前置在密文之前)
  2. DES-ECB-PKCS5(无 IV,直接输出 hex)

Python3(依赖 pycryptodome)

加密

1、AES-CBC-PKCS7 加密

IV 随机生成并拼在密文前

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import binascii

def aes_encrypt(plain_text: str, key: str) -> str:
    """
    腾讯云 HTTPDNS AES 加密
    :param plain_text: 明文(如 "112.30.175.208;117.148.128.189")
    :param key:        16 字节 AES 密钥
    :return:           hex 字符串(前 32 字符为 IV)
    """
    if len(key) != 16:
        raise ValueError('AES key 长度必须为 16 字节')

    iv = get_random_bytes(16)          # 随机 IV
    cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
    ct = cipher.encrypt(pad(plain_text.encode(), AES.block_size))
    return binascii.hexlify(iv + ct).decode()

2、DES-ECB-PKCS5 加密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad
import binascii

def des_encrypt(plain_text: str, key: str) -> str:
    """
    腾讯云 HTTPDNS DES 加密
    :param plain_text: 明文
    :param key:        8 字节 DES 密钥
    :return:           hex 字符串
    """
    if len(key) != 8:
        raise ValueError('DES key 长度必须为 8 字节')

    cipher = DES.new(key.encode(), DES.MODE_ECB)
    ct = cipher.encrypt(pad(plain_text.encode(), DES.block_size))
    return binascii.hexlify(ct).decode()

快速自测

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
if __name__ == '__main__':
    key16 = 'dnspodaespasswrd'
    key8  = 'dnspodpa'
    ip_str = '112.30.175.208;117.148.128.189'

    aes_ct = aes_encrypt(ip_str, key16)
    des_ct = des_encrypt(ip_str, key8)

    print('AES 密文:', aes_ct)
    print('DES 密文:', des_ct)

    # 解密验证
    from aes_des_decrypt import aes_decrypt, des_decrypt
    assert aes_decrypt(aes_ct, key16) == ip_str
    assert des_decrypt(des_ct, key8) == ip_str
    print('加解密闭环验证通过')

运行示例(每次 AES 结果因 IV 随机而不同):

1
2
AES 密文: 7d39a3f2b3e1c8d4f6a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1
DES 密文: fb37fabc98a2f71fca87f9cb259f74a03cc2254f80219f52

解密

下面给出两段可直接使用的参考实现,分别对应腾讯云 HTTPDNS 官方文档中描述的 AES-CBC-PKCS7 和 DES-ECB-PKCS5 解密流程。以 Python3 为例,依赖库仅使用常见的 pycryptodome。

1、AES-CBC-PKCS7 解密

响应体为 hex 字符串,前 16 B 为 IV

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import binascii

def aes_decrypt(cipher_hex: str, key: str) -> str:
    """
    腾讯云 HTTPDNS AES 解密
    :param cipher_hex: 接口返回的 hex 字符串(含前 16 B IV)
    :param key:        16 字节 AES 密钥
    :return:           明文(; 分隔的 IP 列表)
    """
    if len(key) != 16:
        raise ValueError('AES key 长度必须为 16 字节')

    data = binascii.unhexlify(cipher_hex)
    iv, ct = data[:16], data[16:]

    cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
    plain = unpad(cipher.decrypt(ct), AES.block_size)
    return plain.decode()

使用示例(对应文档用例):

1
2
3
4
cipher = 'f689db945693bde440729ec30fb3824c739838a72a30777b123dd1b8e0bb89de4c57d546e74f96ceab2664c3bb68485024339ad198675ac59e2cb5b60e726eb234609ac1c7c0925449f3f505f22104e48de7b2ee19aede451b09691c6826bea3'
key = 'dnspodaespasswrd'
print(aes_decrypt(cipher, key))
# 输出:112.30.175.208;117.148.128.189;117.163.48.119;36.150.211.79;111.48.99.206

2、DES-ECB-PKCS5 解密

响应体为 hex 字符串,无 IV

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import DES
from Crypto.Util.Padding import unpad
import binascii

def des_decrypt(cipher_hex: str, key: str) -> str:
    """
    腾讯云 HTTPDNS DES 解密
    :param cipher_hex: 接口返回的 hex 字符串
    :param key:        8 字节 DES 密钥
    :return:           明文(; 分隔的 IP 列表)
    """
    if len(key) != 8:
        raise ValueError('DES key 长度必须为 8 字节')

    ct = binascii.unhexlify(cipher_hex)
    cipher = DES.new(key.encode(), DES.MODE_ECB)
    plain = unpad(cipher.decrypt(ct), DES.block_size)
    return plain.decode()

使用示例(对应文档用例):

1
2
3
4
cipher = 'fb37fabc98a2f71fca87f9cb259f74a03cc2254f80219f520a6fd36d0ad3eb4380be921f7a491fa4e4d84824286fec3df7d615b5e337b2ecf789bbb6db97e9df5533cefd5c41fb7503c0e8fa99cf0c20'
key = 'dnspodpa'
print(des_decrypt(cipher, key))
# 输出:117.148.128.189;36.150.211.79;111.48.99.206;112.30.175.208;117.163.48.119

依赖安装

1
pip3 install pycryptodome

以上代码已按官方文档要求实现: - AES:CBC 模式,PKCS7,hex 解码后取前 16 B 作 IV
- DES:ECB 模式,PKCS5,hex 解码后直接解密

对应的效果如下:

httpdns-encode

HTTP 请求方式查询

除此之外,在海外也可以参考cloudflare的方式调用,不过cloudflare无法直接以http的方式解析,需要自行封装。

cloudflare-dnsovertls

cloudflare dns over tls

捐赠本站(Donate)

weixin_pay
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))