C# 长字节数组的解密
我想解密一个长字节[],但我无法做到这一点 接收代码:我直接从流中读取C# 长字节数组的解密,c#,python,encryption,cryptography,aes,C#,Python,Encryption,Cryptography,Aes,我想解密一个长字节[],但我无法做到这一点 接收代码:我直接从流中读取位图(按预期工作),然后使用内存流将其转换为字节[],然后对整个字节[]进行解密,然后解密的数据应转换为位图: Bitmap bmpTmp = BitmapFactory.DecodeStream(CommunicationHandler.GetStream()); MemoryStream stream = new MemoryStream(); bmpTmp.Compress(Bitmap.CompressFormat.P
位图
(按预期工作),然后使用内存流
将其转换为字节[]
,然后对整个字节[]
进行解密,然后解密的数据应转换为位图
:
Bitmap bmpTmp = BitmapFactory.DecodeStream(CommunicationHandler.GetStream());
MemoryStream stream = new MemoryStream();
bmpTmp.Compress(Bitmap.CompressFormat.Png, 100, stream);
string imageString = DecryptStringFromBytes_Aes(stream.ToArray());
顺便说一句,我将流读入位图
,然后将其转换为字节[]
,而不是将流直接读入字节[]
,唯一的原因是我没有找到任何函数将网络流
直接读入字节[]
。
我想知道,BitmapFactory.DecodeStream()
是如何工作的?为什么这个函数读取整个数据?它如何知道何时停止
解密代码:
public static string DecryptStringFromBytes_Aes(byte[] cipherTextCombined)
{
string plaintext = null;
// Create an Aes object with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Mode = CipherMode.CBC;
byte[] IV = new byte[16];
byte[] cipherText = new byte[cipherTextCombined.Length - IV.Length];
Array.Copy(cipherTextCombined, IV, IV.Length);
Array.Copy(cipherTextCombined, IV.Length, cipherText, 0, cipherText.Length);
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
plaintext = srDecrypt.ReadToEnd(); //The error occurs here:
//System.ArgumentException: Offset and length were out of bounds for the array or count is
//greater than the number of elements from index to the end of the source collection.
}
return plaintext.TrimEnd('\0');
}
def encrypt(self, message):
message = self.pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(str.encode(self.key), AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
加密代码:
public static string DecryptStringFromBytes_Aes(byte[] cipherTextCombined)
{
string plaintext = null;
// Create an Aes object with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Mode = CipherMode.CBC;
byte[] IV = new byte[16];
byte[] cipherText = new byte[cipherTextCombined.Length - IV.Length];
Array.Copy(cipherTextCombined, IV, IV.Length);
Array.Copy(cipherTextCombined, IV.Length, cipherText, 0, cipherText.Length);
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
plaintext = srDecrypt.ReadToEnd(); //The error occurs here:
//System.ArgumentException: Offset and length were out of bounds for the array or count is
//greater than the number of elements from index to the end of the source collection.
}
return plaintext.TrimEnd('\0');
}
def encrypt(self, message):
message = self.pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(str.encode(self.key), AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
填充代码:
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
这是我通过网络流发送的内容:
import mss.tools
def screenshot():
with mss.mss() as sct:
return sct.grab(sct.monitors[1])
socket.send(mss.tools.to_png(image.rgb, image.size))
根据我得到的错误-System.ArgumentException:偏移量和长度超出了数组的界限,或者计数大于从索引到源集合结尾的元素数。
,我认为输入太长。这是错误堆栈跟踪:位于Project.LoadingImage.RunInBackground(Java.Lang.Void[]参数)[0x0004d]
请注意,这些方法和系统可以完美地使用简单和简短的输入,但唯一的问题是图像,可能是因为byte[]
输入太大,正如错误所暗示的那样
另外,请注意,解密方法返回的是string
而不是byte[]
,这使得将其解码为位图变得更加复杂
作为结论,有3个主要问题:
这个错误意味着什么?我怎样才能解决它
BitmapFactory.DecodeStream()
如何读取整个流?它是如何工作的
有没有办法将解密函数的返回类型从string
更改为byte[]
为什么要从密文的开头减去IV?IV用作AES算法中的初始状态,不包含在输出消息中。IV和密钥都是私有项,只有发送方和接收方知道。只有加密的数据才能通过公共渠道。据我所知,IV不必是私有的。因为在每次加密中都会产生一个新的随机IV,它会随消息一起发送。“根据我得到的错误,…”在您的问题中包括完整的错误消息和/或错误/异常的堆栈跟踪。@SteveTodd这不完全正确。我认为IV通过通信通道也是很常见的——回想一下,IV不是秘密的,不需要保护,它们只是不可预测。为什么要从密文的开头减去IV?IV用作AES算法中的初始状态,不包含在输出消息中。IV和密钥都是私有项,只有发送方和接收方知道。只有加密的数据才能通过公共渠道。据我所知,IV不必是私有的。因为在每次加密中都会产生一个新的随机IV,它会随消息一起发送。“根据我得到的错误,…”在您的问题中包括完整的错误消息和/或错误/异常的堆栈跟踪。@SteveTodd这不完全正确。我认为静脉注射通过通讯渠道也是很常见的——回想一下,静脉注射不是秘密的,不需要保护,只是不能预测而已。