首页 > 编程问答 >如何解密从 Discord 收到的语音数据?

如何解密从 Discord 收到的语音数据?

时间:2024-07-27 16:24:28浏览次数:11  
标签:python discord discord.py udp pynacl

我正在尝试解密从使用 xsalsa20_poly1305 加密模式的 Discord 收到的语音数据。我的目标是录制并使用音频与 AI 聊天。

我可能做错了什么?感谢您的帮助!

我的代码:

async def record_audio(udp_socket, ssrc, secret_key):
    box = nacl.secret.SecretBox(bytes(secret_key)) # TODO: Fix decryption xsalsa20_poly1305
    print("Listening for audio data...")

    try:
        response, _ = udp_socket.recvfrom(74)
        print(f"Received response: {response}")
        # Process the response...
    except socket.timeout:
        print("IP discovery timeout")
    except Exception as e:
        print(f"Unexpected error during IP discovery: {e}")
        return None, None

    while True:
        print("Waiting for audio data...")
        try:
            ready, _, _ = select.select([udp_socket], [], [], 5.0)
            if udp_socket in ready:
                data, addr = udp_socket.recvfrom(65536)  # Adjust buffer size as necessary
                print(f"Received {len(data)} bytes from {addr}: {data.hex()}")

                if len(data) > 12:

                    # Extract the RTP header
                    header = data[:12]

                    # Construct the nonce
                    nonce = header + b'\x00' * 12

                    print(f"Nonce: {len(nonce)} bytes")

                    # Get the encrypted audio data
                    encrypted = data[12:]

                    print(f"Encrypted audio data: {len(encrypted)} bytes")


                    #The rest of the data is the encrypted audio data (Should be 48 - 24 = 24 bytes)


                    #nonce  = data[:12]

                    #print(f"Nonce: {nonce}")

                    #if len(nonce) < 12:
                    #    nonce.ljust(24, b'\x00')
                    #remaining 12 bytes can be zeros or another fixed pattern
                    #nonce = nonce_part + bytes(12)
                    #copy the RTP header to get the nonce
                    #nonce = bytearray(24)
                    #nonce[:12] = data[:12]#data[:12]

                    #get the encrypted audio data
                    #encrypted = data[12:]
                    print(f"Encrypted audio data: {bytes(encrypted)}")
                    try:
                        audio_data = box.decrypt(bytes(data), bytes(nonce))
                        print("Received audio data")
                    except Exception as e:
                        print(f"Decryption error: {e}")
        except Exception as e:
            print(f"Error receiving audio data: {e}")
            break

编辑:密钥直接从从 Discord 收到的操作码 4 对象传递。

输出:

Waiting for audio data...
Received 48 bytes from ('66.22.243.22', 50023): 81c9000700013adfaf6439133ca81bfcd2b35eb743f2a4af0165e3cf0517d8efee5dae36ec6653c88a2d625064af33d6
Nonce: 24 bytes
Nonce: b'\x81\xc9\x00\x07\x00\x01:\xdf\xafd9\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Encrypted audio data: 36 bytes
Encrypted audio data: b'<\xa8\x1b\xfc\xd2\xb3^\xb7C\xf2\xa4\xaf\x01e\xe3\xcf\x05\x17\xd8\xef\xee]\xae6\xecfS\xc8\x8a-bPd\xaf3\xd6'
Decryption error: Decryption failed. Ciphertext failed verification

出于安全原因,我不能包含我的 Discord 令牌但有一些测试数据:

{'op': 4, 'd': {'video_codec': 'H264', 'secure_frames_version': 0, 'secret_key': [20, 115, 239, 10, 206, 186, 11, 248, 52, 47, 193, 69, 170, 89, 146, 187, 215, 181, 4, 177, 173, 132, 50, 212, 141, 194, 52, 217, 219, 17, 111, 5], 'mode': 'xsalsa20_poly1305', 'media_session_id': '77d90ef5c4aa124c0dcd6d39bbe88f9f', 'audio_codec': 'opus'}}
Udp socket:  <socket.socket fd=604, family=2, type=2, proto=0, laddr=('0.0.0.0', 56866)>
SSRC:  112825
Secret key:  [20, 115, 239, 10, 206, 186, 11, 248, 52, 47, 193, 69, 170, 89, 146, 187, 215, 181, 4, 177, 173, 132, 50, 212, 141, 194, 52, 217, 219, 17, 111, 5]
Received data: b'\x81\xc9\x00\x07\x00\x00gIZ.Y\xaf\xf8\x94\xb4a}?gm"\xc6R\x02\\\x13\xaf>@\xf0\xe8\xca\xd0\x90\xf3\x16\x89h\x14\x81s\xa0\x00\xf3$v\x99|'

字节数组中的所有内容:

Data: [129, 201, 0, 7, 0, 1, 87, 149, 132, 179, 156, 19, 161, 42, 79, 112, 160, 142, 72, 43, 68, 43, 225, 201, 66, 97, 38, 88, 120, 123, 192, 102, 18, 163, 126, 210, 96, 21, 113, 212, 66, 63, 102, 7, 123, 24, 141, 1]
RTP header: [129, 201, 0, 7, 0, 1, 87, 149, 132, 179, 156, 19]
Nonce: [129, 201, 0, 7, 0, 1, 87, 149, 132, 179, 156, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Voice data: [161, 42, 79, 112, 160, 142, 72, 43, 68, 43, 225, 201, 66, 97, 38, 88, 120, 123, 192, 102, 18, 163, 126, 210, 96, 21, 113, 212, 66, 63, 102, 7, 123, 24, 141, 1]

几乎要成功解密 Discord 语音数据了!的代码中存在一些小错误,导致解密失败。以下是需要修复的地方:

  1. Nonce 构造: 正在使用整个 RTP 标头加上 12 个零字节来构造 nonce。虽然 RTP 标头的一部分确实用于 nonce,但它不是整个标头。根据 Discord 的文档,应该使用 RTP 标头的 前 12 个字节作为 nonce 无需添加任何额外字节

  2. 解密输入数据: 整个 UDP 数据包 传递给 box.decrypt() 函数,而实际上应该只传递 加密的语音数据 。请记住,UDP 数据包包含一个 12 字节的 RTP 标头,后面才是加密数据。

以下是代码的更正版本:

async def record_audio(udp_socket, ssrc, secret_key):
    box = nacl.secret.SecretBox(bytes(secret_key))
    print("Listening for audio data...")

    # ... (IP discovery code remains unchanged)

    while True:
        print("Waiting for audio data...")
        try:
            ready, _, _ = select.select([udp_socket], [], [], 5.0)
            if udp_socket in ready:
                data, addr = udp_socket.recvfrom(65536)
                print(f"Received {len(data)} bytes from {addr}: {data.hex()}")

                if len(data) > 12:
                    # Extract the RTP header and encrypted data
                    header = data[:12]
                    encrypted_data = data[12:]

                    # Use the first 12 bytes of the RTP header as the nonce
                    nonce = header

                    print(f"Nonce: {nonce.hex()}")
                    print(f"Encrypted audio data: {encrypted_data.hex()}")

                    try:
                        # Decrypt only the encrypted audio data
                        audio_data = box.decrypt(encrypted_data, nonce)
                        print("Received audio data")
                        # Process the decrypted audio data here
                    except Exception as e:
                        print(f"Decryption error: {e}")
        except Exception as e:
            print(f"Error receiving audio data: {e}")
            break

通过这些更改,应该能够成功解密从 Discord 收到的语音数据。然后,可以使用该音频数据与 AI 聊天。

注意: 修改 Discord 客户端的行为(例如录制语音数据)可能违反 Discord 的服务条款。请谨慎操作并确保了解相关规定。

标签:python,discord,discord.py,udp,pynacl
From: 78797300

相关文章

  • 基于python的出租车管理网站的设计与实现【源码+文档+PPT】
    ......
  • 如何在Linux上的python中以后台模式打开程序?
    我需要在Linux上以后台模式使用python打开另一个程序。我尝试过subprocess.call("yourcommand")但它不是后台模式。并且os.startfile("file")在Linux上不起作用。请帮助我。可以使用Python的subprocess模块在Linux上以后台模......
  • 【学习笔记】Matlab和python双语言的学习(TOPSIS法)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、TOPSIS法1.模型原理2.基本步骤(1)原始矩阵正向化(2)正向矩阵标准化(3)计算得分并归一化二、代码实现----Matlab1.主程序2.正向化处理函数3.极小型正向化函数4.中间型正向化函数5.区间型正向化......
  • 基于Python flask 的豆瓣电影top250数据评分可视化
    跟着CSDN上学习一下爬虫和简单的可视化分析,最后完成了一个简单的小项目。1.项目简介        基于Pythonflask的豆瓣电影评分可视化。通过采用Python编程语言,使用flask框架搭建影视系统,并使用相关技术实现对豆瓣网站的爬取、数据存储和可视化分析。2、成果展示:......
  • 获取 Python Decimal 的精确十进制字符串表示形式?
    如果我有一个PythonDecimal,我怎样才能可靠地获得数字的精确十进制字符串(即不是科学记数法)表示而不带尾随零?例如,如果我有:>>>d=Decimal('1e-14')我会像:>>>get_decimal_string(d)'0.00000000000001'但是:Decimal类没有任何to_......
  • python datetime timedelta 对于没有小数部分的时间返回 0.0
    我正在使用datetime.timedelta来获取python中进程的持续时间。defget_time_difference(start_time,end_time):time_in_seconds=(end_time-start_time)returnstr(datetime.timedelta(seconds=time_in_seconds))[:-3]文档指出“所有参数都是可选的......
  • 如何运行从我正在编写的另一个 Python 脚本获取命令行参数的 Python 脚本?
    我有一个python3脚本,如下所示:...defmain():parser=argparse.ArgumentParser(description='Performnormalisationchecksonpass2files')parser.add_argument('-p','--parser',action='store',help='parse......
  • Python 抓取 urllib2 HTTP 错误
    我正在尝试抓取一个网站,但我的代码仅在我打开该网站然后刷新它时才有效。我尝试了多种方法,但不断出现以下两个错误:第一个:ValueError:“HTTPError:HTTP错误416:请求的范围无法满足”urlslist=open("list_urls.txt").read()urlslist=urlslist.split("\n")forurlslistinurl......
  • 【Python】利用 face_recognition 库进行人脸检测识别【附完整示例】
    1.背景条件1.1安装所需库首先安装face_recognition和Pillow这两个库。您可以使用以下命令来安装它们:pipinstallface_recognitionPillow-ihttps://pypi.tuna.tsinghua.edu.cn/simple1.2拷贝代码安装完成后,您就可以在本地运行以下提供的代码了。importfac......
  • 太强了,Python+Excel真的是神仙组合!
    本书是由流行开源Python库xlwings的创始人:费利克斯·朱姆斯坦(FelixZumstein)所撰写。他详细阐述了如何将Python与Excel结合使用,让任务自动化,从而实现效率飞跃。为了帮助初学者克服对Python的恐惧,作者特意将教程内容设计成从简单到复杂的顺序进行介绍。这本书PDF共282页,分为4个......