Skip to content

Commit

Permalink
feat: fix security issue in AES
Browse files Browse the repository at this point in the history
you NEVER use v0.0.x version
  • Loading branch information
elecbug committed Sep 11, 2024
1 parent 017445f commit 52771f8
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 141 deletions.
100 changes: 99 additions & 1 deletion SecSess/Interface/IStream.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using SecSess.Tcp;
using SecSess.Secure;
using SecSess.Tcp;
using System.Net.Sockets;
using System.Security.Cryptography;
using static SecSess.Tcp.Server;

namespace SecSess.Interface
{
Expand All @@ -7,6 +11,100 @@ namespace SecSess.Interface
/// </summary>
public interface IStream
{
/// <summary>
/// Internal real implementation of a Write method
/// </summary>
/// <param name="data">Data that write</param>
/// <param name="aes">AES support wrapper</param>
/// <param name="client">A TCP client that actually works</param>
internal static void InternalWrite(byte[] data, AESWrapper aes, TcpClient client)
{
byte[] iv = new byte[16];
new Random().NextBytes(iv);

byte[] lenBit = BitConverter.GetBytes(data.Length);
byte[] msg = new byte[data.Length + 4];

for (int i = 0; i < 4; i++)
{
msg[i] = lenBit[i];
}
for (int i = 0; i < data.Length; i++)
{
msg[i + 4] = data[i];
}

byte[] enc = aes.Encrypt(msg, iv);
byte[] packet = new byte[16 + enc.Length];

for (int i = 0; i < 16; i++)
{
packet[i] = iv[i];
}
for (int i = 0; i < enc.Length; i++)
{
packet[i + 16] = enc[i];
}

client.GetStream().Write(packet, 0, packet.Length);
}

/// <summary>
/// Internal real implementation of a Read method
/// </summary>
/// <param name="aes">AES support wrapper</param>
/// <param name="client">A TCP client that actually works</param>
/// <returns>Data that read</returns>
internal static byte[] InternalRead(AESWrapper aes, TcpClient client)
{
byte[] iv = new byte[16];

int sss = 0;
while (sss < iv.Length)
sss += client.GetStream().Read(iv, sss, iv.Length - sss);

byte[] enc = new byte[16];
int s = 0;
while (s < enc.Length)
s += client.GetStream().Read(enc, s, enc.Length - s);


byte[] msg1 = aes.Decrypt(enc, iv);
iv = enc[0..16];

int len = BitConverter.ToInt32(msg1[0..4]);
int blockCount = (len + 4) / 16 + ((len + 4) % 16 == 0 ? 0 : 1);

byte[] buffer = new byte[(blockCount - 1) * 16];

if (buffer.Length != 0)
{
int ss = 0;
while (ss < buffer.Length)
ss += client.GetStream().Read(buffer, ss, buffer.Length - ss);

byte[] msg2 = aes.Decrypt(buffer, iv);
byte[] data = new byte[len];

int offset = 0;

for (; offset < 12; offset++)
{
data[offset] = msg1[offset + 4];
}
for (; offset < data.Length; offset++)
{
data[offset] = msg2[offset - 12];
}

return data;
}
else
{
return msg1[4..(len + 4)];
}
}

public abstract void Write(byte[] data);
public abstract byte[] Read();
public abstract bool CanUseStream(StreamType type = StreamType.All);
Expand Down
73 changes: 2 additions & 71 deletions SecSess/Tcp/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ public class Client : IStream
/// </summary>
private IPEndPoint _serverPoint;
/// <summary>
/// Initial vector for sent AES packet
/// </summary>
private byte[] _sentIV;
/// <summary>
/// Initial vector for received AES packet
/// </summary>
private byte[] _receivedIV;
/// <summary>
/// AES support wrapper
/// </summary>
private AESWrapper _aesWrapper { get; set; }
Expand All @@ -50,9 +42,6 @@ private Client(IPEndPoint endPoint, RSAParameters rsa)
_aesKey = new byte[32];
_aesWrapper = new AESWrapper(_aesKey);

_sentIV = new byte[16];
_receivedIV = new byte[16];

new Random(DateTime.Now.Microsecond).NextBytes(_aesKey);
}

Expand Down Expand Up @@ -119,9 +108,6 @@ public void Connect()

string res = new AESWrapper(_aesKey).Decrypt(buffer, new byte[16]).GetString();

_sentIV = _aesKey[0..16];
_receivedIV = _aesKey[16..32];

_aesWrapper = new AESWrapper(_aesKey);

if (res.StartsWith("OK") == false)
Expand All @@ -144,22 +130,7 @@ public void Close()
/// <param name="data">Data that write to server</param>
public void Write(byte[] data)
{
byte[] lenBit = BitConverter.GetBytes(data.Length);
byte[] msg = new byte[data.Length + 4];

for (int i = 0; i < 4; i++)
{
msg[i] = lenBit[i];
}
for (int i = 0; i < data.Length; i++)
{
msg[i + 4] = data[i];
}

byte[] enc = _aesWrapper.Encrypt(msg, _sentIV);
_client.GetStream().Write(enc, 0, enc.Length);

_sentIV = enc[0..16];
IStream.InternalWrite(data, _aesWrapper, _client);
}

/// <summary>
Expand All @@ -168,47 +139,7 @@ public void Write(byte[] data)
/// <returns>Data that read from server</returns>
public byte[] Read()
{
byte[] enc = new byte[16];
int s = 0;
while (s < enc.Length)
s += _client.GetStream().Read(enc, s, enc.Length - s);


byte[] msg1 = _aesWrapper.Decrypt(enc, _receivedIV);
_receivedIV = enc[0..16];

int len = BitConverter.ToInt32(msg1[0..4]);
int blockCount = (len + 4) / 16 + ((len + 4) % 16 == 0 ? 0 : 1);

byte[] buffer = new byte[(blockCount - 1) * 16];

if (buffer.Length != 0)
{
int ss = 0;
while (ss < buffer.Length)
ss += _client.GetStream().Read(buffer, ss, buffer.Length - ss);

byte[] msg2 = _aesWrapper.Decrypt(buffer, _receivedIV);

byte[] data = new byte[len];

int offset = 0;

for (; offset < 12; offset++)
{
data[offset] = msg1[offset + 4];
}
for (; offset < data.Length; offset++)
{
data[offset] = msg2[offset - 12];
}

return data;
}
else
{
return msg1[4..(len + 4)];
}
return IStream.InternalRead(_aesWrapper, _client);
}

/// <summary>
Expand Down
70 changes: 2 additions & 68 deletions SecSess/Tcp/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ public class Client : IStream
/// AES support wrapper
/// </summary>
internal AESWrapper AESWrapper { get; set; }
/// <summary>
/// Initial vector for sent AES packet
/// </summary>
private byte[] _sentIV;
/// <summary>
/// Initial vector for received AES packet
/// </summary>
private byte[] _receivedIV;

/// <summary>
/// Create a server side client
Expand All @@ -50,9 +42,6 @@ internal Client(TcpClient client, byte[] aesKey)
InnerClient = client;
AESKey = aesKey;
AESWrapper = new AESWrapper(aesKey);

_sentIV = aesKey[16..32];
_receivedIV = aesKey[0..16];
}

/// <summary>
Expand All @@ -61,22 +50,7 @@ internal Client(TcpClient client, byte[] aesKey)
/// <param name="data">Data that write to client</param>
public void Write(byte[] data)
{
byte[] lenBit = BitConverter.GetBytes(data.Length);
byte[] msg = new byte[data.Length + 4];

for (int i = 0; i < 4; i++)
{
msg[i] = lenBit[i];
}
for (int i = 0; i < data.Length; i++)
{
msg[i + 4] = data[i];
}

byte[] enc = AESWrapper.Encrypt(msg, _sentIV);
InnerClient.GetStream().Write(enc, 0, enc.Length);

_sentIV = enc[0..16];
IStream.InternalWrite(data, AESWrapper, InnerClient);
}

/// <summary>
Expand All @@ -85,47 +59,7 @@ public void Write(byte[] data)
/// <returns>Data that read from client</returns>
public byte[] Read()
{
byte[] enc = new byte[16];
int s = 0;
while (s < enc.Length)
s += InnerClient.GetStream().Read(enc, s, enc.Length - s);


byte[] msg1 = AESWrapper.Decrypt(enc, _receivedIV);
_receivedIV = enc[0..16];

int len = BitConverter.ToInt32(msg1[0..4]);
int blockCount = (len + 4) / 16 + ((len + 4) % 16 == 0 ? 0 : 1);

byte[] buffer = new byte[(blockCount - 1) * 16];

if (buffer.Length != 0)
{
int ss = 0;
while (ss < buffer.Length)
ss += InnerClient.GetStream().Read(buffer, ss, buffer.Length - ss);

byte[] msg2 = AESWrapper.Decrypt(buffer, _receivedIV);

byte[] data = new byte[len];

int offset = 0;

for (; offset < 12; offset++)
{
data[offset] = msg1[offset + 4];
}
for (; offset < data.Length; offset++)
{
data[offset] = msg2[offset - 12];
}

return data;
}
else
{
return msg1[4..(len + 4)];
}
return IStream.InternalRead(AESWrapper, InnerClient);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.0.4
v0.1.0

0 comments on commit 52771f8

Please sign in to comment.