1

I am trying to record audio raw data in python, ecrypt data and send it to .NET server where I decrypting received data and converting to byte array. When I converting received data to byte array like this Encoding.ASCII.GetBytes(decryptedData) everything is almost working. But maximum byte value is 63 and maximum byte value of sending data is 255. Example of sent and received data:

Sent data

3, 0, 3, 0, 3, 0, 4, 0, 4, 0, 2, 0, 252, 255, 1, 0, 255, 255, 1, 0, 0, 0...

Received data

3, 0, 3, 0, 3, 0, 4, 0, 4, 0, 2, 0, 63, 63, 1, 0, 63, 63, 1, 0, 0, 0...

When I converting received data to byte array like this Encoding.UTF8.GetBytes(DecryptData(aes, data)) everything is almost working. But high value is different. Example of sent and received data:

Sent data

6, 0, 8, 0, 250, 255, 255, 255, 3, 0, 6, 0, 2, 0, 4, 0, 3, 0, 6, 0, 3, 0...

Received data

6, 0, 8, 0, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 3, 0, 6, 0, 2, 0, 4, 0, 3, 0, 6, 3, 0...

It seems like that converting generating more variables. I don't know.

Here is code of python of recording, encrypt and sending data:

import pyaudio
import sys
import socket
import struct
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

key = b"bpjAqrgO2N8q7Rfj8IHzeRxmP1W4HwUTWCRi7DQgyDc="
iv = b"Ta6e1cZAWQMM0QI66JC74w=="

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5

pya = pyaudio.PyAudio()

stream = pya.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, output=True, frames_per_buffer=chunk)

print ("recording")
for i in range(0, 44100 // chunk * RECORD_SECONDS):
    data = stream.read(chunk)
    print (struct.unpack('{}B'.format(len(data)), data))
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    cipher_suite = AES.new(base64.urlsafe_b64decode(key), AES.MODE_CBC, base64.urlsafe_b64decode(iv))
    cipher_text = cipher_suite.encrypt(pad(data, 16))
    sock.sendto(cipher_text, (UDP_IP, UDP_PORT))
    input ()
    # check for silence here by comparing the level with 0 (or some threshold) for 
    # the contents of data.
    # then write data or not to a file

print ("done")

stream.stop_stream()
stream.close()
pya.terminate()

Here is code of C# of receive, decrypt and convert data:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DOTNETServer
{
    class Program
    {
        private static string IP = "127.0.0.1";
        private static int Port = 5005;
        private static string Key = "bpjAqrgO2N8q7Rfj8IHzeRxmP1W4HwUTWCRi7DQgyDc=";
        private static string IV = "Ta6e1cZAWQMM0QI66JC74w==";

        static void Main(string[] args)
        {
            UDPServer(IPAddress.Parse(IP), Port);
            Console.ReadKey();
        }

        private static void UDPServer(IPAddress IP, int Port)
        {
            byte[] data = new byte[32768];
            IPEndPoint endPoint = new IPEndPoint(IP, Port);
            UdpClient client = new UdpClient(endPoint);

            SymmetricAlgorithm aes = new AesManaged();
            aes.KeySize = 256;
            aes.Key = Convert.FromBase64String(Key);
            aes.IV = Convert.FromBase64String(IV);

            while (true)
            {
                Console.WriteLine("Waiting for data.");
                data = client.Receive(ref endPoint);
                var convertedReceivedData = Encoding.ASCII.GetBytes(DecryptData(aes, data));
                Console.Write("(");
                foreach(var item in convertedReceivedData)
                {
                    Console.Write(item + ", ");
                }
                Console.Write(")");
            }
        }

        static byte[] EncryptText(SymmetricAlgorithm aesAlgorithm, string text)
        {
            ICryptoTransform encryptor = aesAlgorithm.CreateEncryptor(aesAlgorithm.Key, aesAlgorithm.IV);
            byte[] data = new byte[32768];
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter writer = new StreamWriter(cs))
                    {
                        writer.Write(text);
                    }
                }
                data = ms.ToArray();
            }

            return data;
        }

        static string DecryptData(SymmetricAlgorithm aes, byte[] data)
        {
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            byte[] encryptedDataBuffer = data;
            string plainText = "";
            using (MemoryStream ms = new MemoryStream(encryptedDataBuffer))
            {
                using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader reader = new StreamReader(cs))
                    {
                        plainText = reader.ReadToEnd();
                    }
                }
            }

            return plainText;
        }
    }
}
8
  • The code in your server suggests that the decrypted data consist of text characters (why else would it use a StreamReader on the decrypted data stream, right?). But your Python code suggests (as far as i can tell) that the encrypted data are the "raw binary" bytes of the audio samples. So, unless i overlooked something or am otherwise mistaken, your server code does not match your client code on a conceptual level, as the server code seems to expect a different kind of encrypted data (text) than what the Python client delivers (non-text bytes). Commented Mar 31, 2019 at 15:35
  • Note that a text character is not synonymous with a byte and vice versa. Depending on the text encoding used, not all possible byte values can be translated to a character (such as with ASCII), or more than one byte (multiple bytes) will translate to only one character (such as with UTF-8). If you want to process byte data as byte data, why would you mess around with trying to interpret/process the byte data as text? Commented Mar 31, 2019 at 15:38
  • By the way, as a side note with regard to why you see the value 63 popping up there: 63 is the ASCII value of the character ?, which is apparently being used as a substitute character by Encoding.ASCII.GetBytes for any character in the "plainText" string that is not a valid ASCII character. Commented Mar 31, 2019 at 15:46
  • Yea I know about this but if I am not wrong, its not important. I though when I convert string back to byte array its same... Probably not... With normal message like text, string, after converting to byte array on client and then encrypt and sent and then received and decrpyt, message is fine. I though its all just about byte array converting. And CryptoStream doesn't suppport Write... I will try another way to decrypt probably... Commented Mar 31, 2019 at 15:48
  • Never, Never, Never take binary data an encode. It will corrupt the data. ASCII encoding with remove non printable characters which will make it impossible to recreate original data. You can convert to 64 bit stream which is reversible and will gt original data. Commented Mar 31, 2019 at 15:50

1 Answer 1

1

Ok, I resolve my problem with the advice from elgonzo. For sure I print the data byte per byte from data without any converting or unpacking in python like this:

data = stream.read(chunk)
for item in data:
    print (item)

And in .NET application, just encrypt and decrypt with Rijndael what using input byte[] and have byte[] as output like this:

public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)
{
    MemoryStream ms = new MemoryStream();
    Rijndael alg = Rijndael.Create();

    alg.Key = Key;
    alg.IV = IV;

    CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);            
    cs.Write(cipherData, 0, cipherData.Length);
    cs.Close();

    return ms.ToArray();
}

Thank you again and have a good day :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.