new update v1.5

new encrypt system
This commit is contained in:
dharm pimsen 2023-12-18 18:24:23 +07:00
parent 82ba9cf8b4
commit c4c75f10e0
2 changed files with 127 additions and 12 deletions

View File

@ -9,6 +9,9 @@ import pickle
import pyaudio
from pyogg import OpusDecoder
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)"]
@ -37,6 +40,25 @@ def limit_string_in_line(text, limit):
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:
def __init__(self):
self.RDS = None
@ -46,6 +68,10 @@ class App:
self.firstrun = True
self.firststart = True
self.device_index_output = 0
self.ccdecryptpassword = None
self.ccisencrypt = None
self.ccisdecrypt = None
self.ccisdecryptpassword = None
def connecttoserver(self, sender, data):
dpg.configure_item("connectservergroup", show=False)
@ -85,6 +111,10 @@ class App:
dpg.configure_item("serverstatus", default_value='disconnected', color=(255, 0, 0))
self.firstrun = True
self.firststart = True
self.ccdecryptpassword = None
self.ccisencrypt = None
self.ccisdecrypt = None
self.ccisdecryptpassword = None
def RDSshow(self):
try:
@ -110,6 +140,10 @@ class App:
dpg.configure_item("station_logo_config", show=False)
self.readchannel = int(dpg.get_value(sender).split(" ")[0])
self.firstrun = True
self.ccdecryptpassword = None
self.ccisencrypt = None
self.ccisdecrypt = None
self.ccisdecryptpassword = None
p = pyaudio.PyAudio()
@ -120,6 +154,11 @@ class App:
self.device_index_output = dev['index']
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):
opus_decoder = None
streamoutput = None
@ -191,7 +230,7 @@ class App:
if len(datadecoded["channel"]) > 1:
channel_info = []
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("morerdsbutton", show=True)
dpg.configure_item("serverinfobutton", show=True)
@ -205,17 +244,40 @@ class App:
if self.firststart:
self.readchannel = datadecoded["mainchannel"]
dpg.configure_item("mediachannelselect", show=True, default_value="mainchannel")
# 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.firststart = False
if not self.firstrun:
decoded_pcm = opus_decoder.decode(memoryview(bytearray(datadecoded["channel"][self.readchannel]["Content"])))
if len(adcctfrpy) > 250:
adcctfrpy.pop(0)
adcctfrpy.append(len(datadecoded["channel"][self.readchannel]["Content"]))
dpg.set_value('transferateaudiodataoncchannelplot', [tfrpx, adcctfrpy])
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:
@ -225,6 +287,11 @@ class App:
else:
print("Decoded PCM is empty")
if len(adcctfrpy) > 250:
adcctfrpy.pop(0)
adcctfrpy.append(len(datadecoded["channel"][self.readchannel]["Content"]))
dpg.set_value('transferateaudiodataoncchannelplot', [tfrpx, adcctfrpy])
bytesconunt_frame += 1
else:
streamoutput.close()
@ -241,6 +308,7 @@ class App:
pass
socket.close()
self.disconnectserver()
raise
break
def window(self):
@ -330,6 +398,13 @@ class App:
dpg.add_spacer(height=20)
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):
with dpg.viewport_menu_bar():
with dpg.menu(label="File"):

View File

@ -9,6 +9,36 @@ from damp11113 import scrollTextBySteps
from queue import Queue
from datetime import datetime, timezone
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
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -206,9 +236,11 @@ def encode_audio():
encoded_packets = encoder.buffered_encode(memoryview(bytearray(pcm)))
for encoded_packet, _, _ in encoded_packets:
# Put the encoded audio into the buffer
channel1.put(encoded_packet.tobytes())
def encode_audio2():
encoder2 = OpusBufferedEncoder()
encoder2.set_application("audio")
@ -240,18 +272,26 @@ def handle_client():
while True:
# Get the encoded audio from the buffer
ENchannel1 = channel1.get()
# encrypt data
ENC1encrypted, ENC1salt, ENC1iv = encrypt_data(ENchannel1, "password")
ENchannel1 = ENC1encrypted + b'|||||' + ENC1salt + b'|||||' + ENC1iv
ENchannel2 = channel2.get()
content = {
"mainchannel": 1,
"channel": {
1: {
"Station": "DPRadio+",
"Encrypt": b'|||||' in ENchannel1, # check if encrypt
"ContentSize": len(ENchannel1),
"Content": ENchannel1,
"RDS": RDS
},
2: {
"Station": "DPTest",
"Encrypt": b'|||||' in ENchannel2,
"ContentSize": len(ENchannel2),
"Content": ENchannel2,
"RDS": RDS2