繁体   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