我正在开发一个简单的程序,它充当客户端和 HTTP 代理服务器之间的代理,当使用简单的 Stream.copytoasync 函数时,我在从客户端到代理交换数据并返回时没有问题。我尝试使用以下代码修改函数以添加简单的对称加密:
对于加密(客户端,从客户端流复制到服务器流):
public static async Task CopyEncrypt(this Stream source, Stream destination,string encryption_key, CancellationToken cancellationToken = default(CancellationToken), int bufferSize = 0x1000)
{
var buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
{
byte[] eca = Encrypt(buffer, encryption_key);
await destination.WriteAsync(eca, 0, eca.Length, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
}
}
用于解密(服务器端,取客户端发送的数据,转发给http代理):
public static async Task CopyDecrypt(this Stream source, Stream destination,string aeskey, CancellationToken cancellationToken = default(CancellationToken), int bufferSize = 0x1000)
{
var buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
{
byte[] eca = Decrypt(buffer, aeskey);
await destination.WriteAsync(eca, 0, eca.Length, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
}
}
我尝试了多种加密/解密功能,包括 AES、TripleDES、Rijndael。每当将这些与填充一起使用时,我通常会在解密时收到以下错误(对加密和解密使用相同的填充):
Padding is invalid and cannot be removed
在没有任何填充的情况下使用时,数据会被解密,但由于在发送标头后通过 HTTP 代理的过程失败,因此数据似乎没有正确/完整地传输。
虽然该过程在没有加密的情况下可以正常使用以下功能:
对于加密:
public static async Task CopyEncrypt(this Stream source, Stream destination,string encryption_key, CancellationToken cancellationToken = default(CancellationToken), int bufferSize = 0x1000)
{
var buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
}
}
用于解密:
public static async Task CopyDecrypt(this Stream source, Stream destination,string aeskey, CancellationToken cancellationToken = default(CancellationToken), int bufferSize = 0x1000)
{
var buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
}
}
答案 0 :(得分:0)
您的 Encrypt
/Decrypt
函数的签名让我相信他们试图将每个缓冲区视为一条完整的消息。这意味着将向每个缓冲区添加任何填充。
当您使用流时,您需要加密/解密为流。这样,任何填充都只会出现在流的末尾。
最简单的方法是使用 CryptoStream
,然后您可以像复制常规流一样复制加密流。