mirror of
https://github.com/damp11113/IDRB.git
synced 2025-04-27 22:48:09 +00:00
new update v1.5
new encrypt system
This commit is contained in:
parent
82ba9cf8b4
commit
c4c75f10e0
@ -9,6 +9,9 @@ import pickle
|
|||||||
import pyaudio
|
import pyaudio
|
||||||
from pyogg import OpusDecoder
|
from pyogg import OpusDecoder
|
||||||
from damp11113 import CV22DPG
|
from damp11113 import CV22DPG
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
from Crypto.Protocol.KDF import scrypt
|
||||||
|
from Crypto.Random import get_random_bytes
|
||||||
|
|
||||||
librarylist = ["Opencv (opencv.org)", "PyOgg (TeamPyOgg)", "DearPyGui (hoffstadt)"]
|
librarylist = ["Opencv (opencv.org)", "PyOgg (TeamPyOgg)", "DearPyGui (hoffstadt)"]
|
||||||
|
|
||||||
@ -37,6 +40,25 @@ def limit_string_in_line(text, limit):
|
|||||||
|
|
||||||
return '\n'.join(new_lines)
|
return '\n'.join(new_lines)
|
||||||
|
|
||||||
|
def unpad_message(padded_message):
|
||||||
|
padding_length = padded_message[-1]
|
||||||
|
return padded_message[:-padding_length]
|
||||||
|
|
||||||
|
def decrypt_data(encrypted_message, password, salt, iv):
|
||||||
|
# Derive the key from the password and salt
|
||||||
|
key = scrypt(password, salt, key_len=32, N=2 ** 14, r=8, p=1)
|
||||||
|
|
||||||
|
# Initialize AES cipher in CBC mode
|
||||||
|
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||||
|
|
||||||
|
# Decrypt the message
|
||||||
|
decrypted_message = cipher.decrypt(encrypted_message)
|
||||||
|
|
||||||
|
# Unpad the decrypted message
|
||||||
|
unpadded_message = unpad_message(decrypted_message)
|
||||||
|
|
||||||
|
return unpadded_message
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.RDS = None
|
self.RDS = None
|
||||||
@ -46,6 +68,10 @@ class App:
|
|||||||
self.firstrun = True
|
self.firstrun = True
|
||||||
self.firststart = True
|
self.firststart = True
|
||||||
self.device_index_output = 0
|
self.device_index_output = 0
|
||||||
|
self.ccdecryptpassword = None
|
||||||
|
self.ccisencrypt = None
|
||||||
|
self.ccisdecrypt = None
|
||||||
|
self.ccisdecryptpassword = None
|
||||||
|
|
||||||
def connecttoserver(self, sender, data):
|
def connecttoserver(self, sender, data):
|
||||||
dpg.configure_item("connectservergroup", show=False)
|
dpg.configure_item("connectservergroup", show=False)
|
||||||
@ -85,6 +111,10 @@ class App:
|
|||||||
dpg.configure_item("serverstatus", default_value='disconnected', color=(255, 0, 0))
|
dpg.configure_item("serverstatus", default_value='disconnected', color=(255, 0, 0))
|
||||||
self.firstrun = True
|
self.firstrun = True
|
||||||
self.firststart = True
|
self.firststart = True
|
||||||
|
self.ccdecryptpassword = None
|
||||||
|
self.ccisencrypt = None
|
||||||
|
self.ccisdecrypt = None
|
||||||
|
self.ccisdecryptpassword = None
|
||||||
|
|
||||||
def RDSshow(self):
|
def RDSshow(self):
|
||||||
try:
|
try:
|
||||||
@ -110,6 +140,10 @@ class App:
|
|||||||
dpg.configure_item("station_logo_config", show=False)
|
dpg.configure_item("station_logo_config", show=False)
|
||||||
self.readchannel = int(dpg.get_value(sender).split(" ")[0])
|
self.readchannel = int(dpg.get_value(sender).split(" ")[0])
|
||||||
self.firstrun = True
|
self.firstrun = True
|
||||||
|
self.ccdecryptpassword = None
|
||||||
|
self.ccisencrypt = None
|
||||||
|
self.ccisdecrypt = None
|
||||||
|
self.ccisdecryptpassword = None
|
||||||
|
|
||||||
p = pyaudio.PyAudio()
|
p = pyaudio.PyAudio()
|
||||||
|
|
||||||
@ -120,6 +154,11 @@ class App:
|
|||||||
self.device_index_output = dev['index']
|
self.device_index_output = dev['index']
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def submitpassworddecrypt(self, sender, data):
|
||||||
|
dpg.configure_item("requestpasswordpopup", show=False)
|
||||||
|
self.ccdecryptpassword = dpg.get_value("requestpasswordinputpopup")
|
||||||
|
self.ccisdecryptpassword = True
|
||||||
|
|
||||||
def stream(self, socket):
|
def stream(self, socket):
|
||||||
opus_decoder = None
|
opus_decoder = None
|
||||||
streamoutput = None
|
streamoutput = None
|
||||||
@ -191,7 +230,7 @@ class App:
|
|||||||
if len(datadecoded["channel"]) > 1:
|
if len(datadecoded["channel"]) > 1:
|
||||||
channel_info = []
|
channel_info = []
|
||||||
for i in range(1, len(datadecoded["channel"]) + 1):
|
for i in range(1, len(datadecoded["channel"]) + 1):
|
||||||
channel_info.append(f'{i} {datadecoded["channel"][i]["Station"]} ({datadecoded["channel"][i]["RDS"]["ContentInfo"]["Codec"]} {datadecoded["channel"][i]["RDS"]["ContentInfo"]["bitrate"] / 1000}Kbps {datadecoded["channel"][i]["RDS"]["AudioMode"]})')
|
channel_info.append(f'{i} {"[Encrypt]" if datadecoded["channel"][i]["Encrypt"] else "[No Encrypt]"} {datadecoded["channel"][i]["Station"]} ({datadecoded["channel"][i]["RDS"]["ContentInfo"]["Codec"]} {datadecoded["channel"][i]["RDS"]["ContentInfo"]["bitrate"] / 1000}Kbps {datadecoded["channel"][i]["RDS"]["AudioMode"]})')
|
||||||
dpg.configure_item("mediachannelselect", show=True, items=channel_info)
|
dpg.configure_item("mediachannelselect", show=True, items=channel_info)
|
||||||
dpg.configure_item("morerdsbutton", show=True)
|
dpg.configure_item("morerdsbutton", show=True)
|
||||||
dpg.configure_item("serverinfobutton", show=True)
|
dpg.configure_item("serverinfobutton", show=True)
|
||||||
@ -205,26 +244,54 @@ class App:
|
|||||||
if self.firststart:
|
if self.firststart:
|
||||||
self.readchannel = datadecoded["mainchannel"]
|
self.readchannel = datadecoded["mainchannel"]
|
||||||
dpg.configure_item("mediachannelselect", show=True, default_value="mainchannel")
|
dpg.configure_item("mediachannelselect", show=True, default_value="mainchannel")
|
||||||
dpg.configure_item("serverstatus", default_value='connected --Kbps (----)', color=(0, 255, 0))
|
|
||||||
|
# check if channel is encrypted
|
||||||
|
if datadecoded["channel"][self.readchannel]["Encrypt"]:
|
||||||
|
dpg.configure_item("requestpasswordpopup", show=True)
|
||||||
|
dpg.configure_item("serverstatus", default_value='connected', color=(0, 255, 0))
|
||||||
|
self.ccisencrypt = True
|
||||||
|
else:
|
||||||
|
dpg.configure_item("serverstatus", default_value='connected --Kbps (----)', color=(0, 255, 0))
|
||||||
|
|
||||||
self.firstrun = False
|
self.firstrun = False
|
||||||
self.firststart = False
|
self.firststart = False
|
||||||
|
|
||||||
|
|
||||||
if not self.firstrun:
|
if not self.firstrun:
|
||||||
decoded_pcm = opus_decoder.decode(memoryview(bytearray(datadecoded["channel"][self.readchannel]["Content"])))
|
data = datadecoded["channel"][self.readchannel]["Content"]
|
||||||
|
|
||||||
|
if self.ccisdecryptpassword and self.ccisencrypt:
|
||||||
|
try:
|
||||||
|
# decrypt data
|
||||||
|
encryptdata = data.split(b'|||||')[0]
|
||||||
|
salt = data.split(b'|||||')[1]
|
||||||
|
iv = data.split(b'|||||')[2]
|
||||||
|
|
||||||
|
data = decrypt_data(encryptdata, self.ccdecryptpassword, salt, iv)
|
||||||
|
|
||||||
|
if data == b'':
|
||||||
|
self.ccisdecrypt = False
|
||||||
|
self.ccdecryptpassword = None
|
||||||
|
else:
|
||||||
|
self.ccisdecrypt = True
|
||||||
|
except:
|
||||||
|
dpg.configure_item("serverstatus", default_value="Decrypt Error", color=(255, 0, 0))
|
||||||
|
|
||||||
|
if self.ccisdecrypt or not self.ccisencrypt:
|
||||||
|
decoded_pcm = opus_decoder.decode(memoryview(bytearray(data)))
|
||||||
|
|
||||||
|
# Check if the decoded PCM is empty or not
|
||||||
|
if len(decoded_pcm) > 0:
|
||||||
|
pcm_to_write = np.frombuffer(decoded_pcm, dtype=np.int16)
|
||||||
|
|
||||||
|
streamoutput.write(pcm_to_write.tobytes())
|
||||||
|
else:
|
||||||
|
print("Decoded PCM is empty")
|
||||||
|
|
||||||
if len(adcctfrpy) > 250:
|
if len(adcctfrpy) > 250:
|
||||||
adcctfrpy.pop(0)
|
adcctfrpy.pop(0)
|
||||||
adcctfrpy.append(len(datadecoded["channel"][self.readchannel]["Content"]))
|
adcctfrpy.append(len(datadecoded["channel"][self.readchannel]["Content"]))
|
||||||
dpg.set_value('transferateaudiodataoncchannelplot', [tfrpx, adcctfrpy])
|
dpg.set_value('transferateaudiodataoncchannelplot', [tfrpx, adcctfrpy])
|
||||||
|
|
||||||
# Check if the decoded PCM is empty or not
|
|
||||||
if len(decoded_pcm) > 0:
|
|
||||||
pcm_to_write = np.frombuffer(decoded_pcm, dtype=np.int16)
|
|
||||||
|
|
||||||
streamoutput.write(pcm_to_write.tobytes())
|
|
||||||
else:
|
|
||||||
print("Decoded PCM is empty")
|
|
||||||
|
|
||||||
bytesconunt_frame += 1
|
bytesconunt_frame += 1
|
||||||
else:
|
else:
|
||||||
streamoutput.close()
|
streamoutput.close()
|
||||||
@ -241,6 +308,7 @@ class App:
|
|||||||
pass
|
pass
|
||||||
socket.close()
|
socket.close()
|
||||||
self.disconnectserver()
|
self.disconnectserver()
|
||||||
|
raise
|
||||||
break
|
break
|
||||||
|
|
||||||
def window(self):
|
def window(self):
|
||||||
@ -330,6 +398,13 @@ class App:
|
|||||||
dpg.add_spacer(height=20)
|
dpg.add_spacer(height=20)
|
||||||
dpg.add_text(f"Copyright (C) 2023 ThaiSDR All rights reserved. (GPLv3)")
|
dpg.add_text(f"Copyright (C) 2023 ThaiSDR All rights reserved. (GPLv3)")
|
||||||
|
|
||||||
|
with dpg.window(label="Password Required", tag="requestpasswordpopup", modal=True, no_resize=True, no_close=True, no_move=True, show=False):
|
||||||
|
dpg.add_text("This channel is encrypt! Please enter password for decrypt.")
|
||||||
|
dpg.add_spacer()
|
||||||
|
dpg.add_input_text(label="password", tag="requestpasswordinputpopup")
|
||||||
|
dpg.add_spacer()
|
||||||
|
dpg.add_button(label="confirm", callback=self.submitpassworddecrypt)
|
||||||
|
|
||||||
def menubar(self):
|
def menubar(self):
|
||||||
with dpg.viewport_menu_bar():
|
with dpg.viewport_menu_bar():
|
||||||
with dpg.menu(label="File"):
|
with dpg.menu(label="File"):
|
||||||
|
@ -9,6 +9,36 @@ from damp11113 import scrollTextBySteps
|
|||||||
from queue import Queue
|
from queue import Queue
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
import cv2
|
import cv2
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
from Crypto.Protocol.KDF import scrypt
|
||||||
|
from Crypto.Random import get_random_bytes
|
||||||
|
|
||||||
|
def pad_message(message_bytes):
|
||||||
|
block_size = AES.block_size
|
||||||
|
padding_length = block_size - (len(message_bytes) % block_size)
|
||||||
|
padding = bytes([padding_length] * padding_length)
|
||||||
|
return message_bytes + padding
|
||||||
|
|
||||||
|
def encrypt_data(message_bytes, password):
|
||||||
|
# Derive a key from the password
|
||||||
|
salt = get_random_bytes(16)
|
||||||
|
key = scrypt(password, salt, key_len=32, N=2 ** 14, r=8, p=1)
|
||||||
|
|
||||||
|
# Generate an IV (Initialization Vector)
|
||||||
|
iv = get_random_bytes(AES.block_size)
|
||||||
|
|
||||||
|
# Pad the message
|
||||||
|
padded_message = pad_message(message_bytes)
|
||||||
|
|
||||||
|
# Initialize AES cipher in CBC mode
|
||||||
|
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||||
|
|
||||||
|
# Encrypt the padded message
|
||||||
|
encrypted_message = cipher.encrypt(padded_message)
|
||||||
|
|
||||||
|
# Return the encrypted message, salt, and IV (for decryption)
|
||||||
|
return encrypted_message, salt, iv
|
||||||
|
|
||||||
|
|
||||||
# create tcp
|
# create tcp
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
@ -206,9 +236,11 @@ def encode_audio():
|
|||||||
encoded_packets = encoder.buffered_encode(memoryview(bytearray(pcm)))
|
encoded_packets = encoder.buffered_encode(memoryview(bytearray(pcm)))
|
||||||
for encoded_packet, _, _ in encoded_packets:
|
for encoded_packet, _, _ in encoded_packets:
|
||||||
# Put the encoded audio into the buffer
|
# Put the encoded audio into the buffer
|
||||||
|
|
||||||
channel1.put(encoded_packet.tobytes())
|
channel1.put(encoded_packet.tobytes())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def encode_audio2():
|
def encode_audio2():
|
||||||
encoder2 = OpusBufferedEncoder()
|
encoder2 = OpusBufferedEncoder()
|
||||||
encoder2.set_application("audio")
|
encoder2.set_application("audio")
|
||||||
@ -240,18 +272,26 @@ def handle_client():
|
|||||||
while True:
|
while True:
|
||||||
# Get the encoded audio from the buffer
|
# Get the encoded audio from the buffer
|
||||||
ENchannel1 = channel1.get()
|
ENchannel1 = channel1.get()
|
||||||
|
|
||||||
|
# encrypt data
|
||||||
|
ENC1encrypted, ENC1salt, ENC1iv = encrypt_data(ENchannel1, "password")
|
||||||
|
|
||||||
|
ENchannel1 = ENC1encrypted + b'|||||' + ENC1salt + b'|||||' + ENC1iv
|
||||||
|
|
||||||
ENchannel2 = channel2.get()
|
ENchannel2 = channel2.get()
|
||||||
content = {
|
content = {
|
||||||
"mainchannel": 1,
|
"mainchannel": 1,
|
||||||
"channel": {
|
"channel": {
|
||||||
1: {
|
1: {
|
||||||
"Station": "DPRadio+",
|
"Station": "DPRadio+",
|
||||||
|
"Encrypt": b'|||||' in ENchannel1, # check if encrypt
|
||||||
"ContentSize": len(ENchannel1),
|
"ContentSize": len(ENchannel1),
|
||||||
"Content": ENchannel1,
|
"Content": ENchannel1,
|
||||||
"RDS": RDS
|
"RDS": RDS
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
"Station": "DPTest",
|
"Station": "DPTest",
|
||||||
|
"Encrypt": b'|||||' in ENchannel2,
|
||||||
"ContentSize": len(ENchannel2),
|
"ContentSize": len(ENchannel2),
|
||||||
"Content": ENchannel2,
|
"Content": ENchannel2,
|
||||||
"RDS": RDS2
|
"RDS": RDS2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user