簡體   English   中英

加密字節數組,從字符串轉換為8位整數數組

[英]Encrypt byte array, converting from string to 8bit integer array

我正在嘗試在 python 中記錄音頻原始數據,ecrypt 數據並將其發送到 .NET 服務器,在那里我解密接收到的數據並轉換為字節數組。 當我將接收到的數據轉換為這樣的字節數組時 Encoding.ASCII.GetBytes(decryptedData) 一切幾乎都在工作。 但最大字節值為 63,發送數據的最大字節值為 255。 發送和接收數據示例:

發送數據

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

接收數據

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

當我將接收到的數據轉換為這樣的字節數組時 Encoding.UTF8.GetBytes(DecryptData(aes, data)) 一切都幾乎正常工作。 但高價值是不同的。 發送和接收數據示例:

發送數據

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

接收數據

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...

似乎轉換會產生更多的變量。 我不知道。

下面是記錄、加密和發送數據的python代碼:

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()

下面是接收、解密和轉換數據的C#代碼:

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;
        }
    }
}

好的,我根據 elgonzo 的建議解決了我的問題。 當然,我從 data 打印每個字節的數據字節,而沒有像這樣在 python 中進行任何轉換或解包:

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

在 .NET 應用程序中,只需使用 Rijndael 加密和解密使用輸入 byte[] 的內容,並將 byte[] 作為輸出,如下所示:

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();
}

再次感謝您,祝您有美好的一天:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM