v0.2.2: updated Lidgren, railgun shells can be bought, autorestart server, netstats, tutorial moloch spawning in a wall fix, misc error checks

This commit is contained in:
Regalis
2015-10-18 22:44:30 +03:00
parent aa3882a815
commit 0e5e86e363
85 changed files with 2763 additions and 1866 deletions
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
namespace Lidgren.Network
{
/// <summary>
/// Interface for an encryption algorithm
/// </summary>
public interface INetEncryption
{
/// <summary>
/// Encrypt an outgoing message in place
/// </summary>
bool Encrypt(NetOutgoingMessage msg);
/// <summary>
/// Decrypt an incoming message in place
/// </summary>
bool Decrypt(NetIncomingMessage msg);
}
}
+9 -155
View File
@@ -1,172 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// AES encryption
/// </summary>
public class NetAESEncryption : INetEncryption
public class NetAESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetAESEncryption()
{
#if !IOS && !__ANDROID__
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in aes.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in aes.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
#endif
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(string key)
: this(key, m_keysizes[0])
public NetAESEncryption(NetPeer peer)
: base(peer, new AesCryptoServiceProvider())
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public NetAESEncryption(NetPeer peer, string key)
: base(peer, new AesCryptoServiceProvider())
{
#if !IOS && !__ANDROID__
try
{
// nested usings are fun!
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
#else
return false;
#endif
SetKey(key);
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new AesCryptoServiceProvider())
{
#if !IOS && !__ANDROID__
try
{
// nested usings are fun!
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
#else
return false;
#endif
SetKey(data, offset, count);
}
}
}
@@ -6,7 +6,7 @@ namespace Lidgren.Network
/// <summary>
/// Base for a non-threadsafe encryption class
/// </summary>
public abstract class NetBlockEncryptionBase : INetEncryption
public abstract class NetBlockEncryptionBase : NetEncryption
{
// temporary space for one block to avoid reallocating every time
private byte[] m_tmp;
@@ -19,7 +19,8 @@ namespace Lidgren.Network
/// <summary>
/// NetBlockEncryptionBase constructor
/// </summary>
public NetBlockEncryptionBase()
public NetBlockEncryptionBase(NetPeer peer)
: base(peer)
{
m_tmp = new byte[BlockSize];
}
@@ -27,7 +28,7 @@ namespace Lidgren.Network
/// <summary>
/// Encrypt am outgoing message with this algorithm; no writing can be done to the message after encryption, or message will be corrupted
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public override bool Encrypt(NetOutgoingMessage msg)
{
int payloadBitLength = msg.LengthBits;
int numBytes = msg.LengthBytes;
@@ -55,7 +56,7 @@ namespace Lidgren.Network
/// </summary>
/// <param name="msg">message to decrypt</param>
/// <returns>true if successful; false if failed</returns>
public bool Decrypt(NetIncomingMessage msg)
public override bool Decrypt(NetIncomingMessage msg)
{
int numEncryptedBytes = msg.LengthBytes - 4; // last 4 bytes is true bit length
int blockSize = BlockSize;
@@ -0,0 +1,77 @@
using System;
using System.IO;
using System.Security.Cryptography;
namespace Lidgren.Network
{
public abstract class NetCryptoProviderBase : NetEncryption
{
protected SymmetricAlgorithm m_algorithm;
public NetCryptoProviderBase(NetPeer peer, SymmetricAlgorithm algo)
: base(peer)
{
m_algorithm = algo;
m_algorithm.GenerateKey();
m_algorithm.GenerateIV();
}
public override void SetKey(byte[] data, int offset, int count)
{
int len = m_algorithm.Key.Length;
var key = new byte[len];
for (int i = 0; i < len; i++)
key[i] = data[offset + (i % count)];
m_algorithm.Key = key;
len = m_algorithm.IV.Length;
key = new byte[len];
for (int i = 0; i < len; i++)
key[len - 1 - i] = data[offset + (i % count)];
m_algorithm.IV = key;
}
public override bool Encrypt(NetOutgoingMessage msg)
{
int unEncLenBits = msg.LengthBits;
var ms = new MemoryStream();
var cs = new CryptoStream(ms, m_algorithm.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(msg.m_data, 0, msg.LengthBytes);
cs.Close();
// get results
var arr = ms.ToArray();
ms.Close();
msg.EnsureBufferSize((arr.Length + 4) * 8);
msg.LengthBits = 0; // reset write pointer
msg.Write((uint)unEncLenBits);
msg.Write(arr);
msg.LengthBits = (arr.Length + 4) * 8;
return true;
}
public override bool Decrypt(NetIncomingMessage msg)
{
int unEncLenBits = (int)msg.ReadUInt32();
var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4);
var cs = new CryptoStream(ms, m_algorithm.CreateDecryptor(), CryptoStreamMode.Read);
var byteLen = NetUtility.BytesToHoldBits(unEncLenBits);
var result = m_peer.GetStorage(byteLen);
cs.Read(result, 0, byteLen);
cs.Close();
// TODO: recycle existing msg
msg.m_data = result;
msg.m_bitLength = unEncLenBits;
msg.m_readPosition = 0;
return true;
}
}
}
@@ -0,0 +1,59 @@
using System;
using System.IO;
using System.Security.Cryptography;
namespace Lidgren.Network
{
public abstract class NetCryptoProviderEncryption : NetEncryption
{
public NetCryptoProviderEncryption(NetPeer peer)
: base(peer)
{
}
protected abstract CryptoStream GetEncryptStream(MemoryStream ms);
protected abstract CryptoStream GetDecryptStream(MemoryStream ms);
public override bool Encrypt(NetOutgoingMessage msg)
{
int unEncLenBits = msg.LengthBits;
var ms = new MemoryStream();
var cs = GetEncryptStream(ms);
cs.Write(msg.m_data, 0, msg.LengthBytes);
cs.Close();
// get results
var arr = ms.ToArray();
ms.Close();
msg.EnsureBufferSize((arr.Length + 4) * 8);
msg.LengthBits = 0; // reset write pointer
msg.Write((uint)unEncLenBits);
msg.Write(arr);
msg.LengthBits = (arr.Length + 4) * 8;
return true;
}
public override bool Decrypt(NetIncomingMessage msg)
{
int unEncLenBits = (int)msg.ReadUInt32();
var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4);
var cs = GetDecryptStream(ms);
var result = m_peer.GetStorage(unEncLenBits);
cs.Read(result, 0, NetUtility.BytesToHoldBits(unEncLenBits));
cs.Close();
// TODO: recycle existing msg
msg.m_data = result;
msg.m_bitLength = unEncLenBits;
return true;
}
}
}
+10 -148
View File
@@ -1,164 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// DES encryption
/// </summary>
public class NetDESEncryption : INetEncryption
public class NetDESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetDESEncryption()
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in des.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in des.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(string key)
: this(key, m_keysizes[0])
public NetDESEncryption(NetPeer peer)
: base(peer, new DESCryptoServiceProvider())
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public NetDESEncryption(NetPeer peer, string key)
: base(peer, new DESCryptoServiceProvider())
{
try
{
// nested usings are fun!
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(key);
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
public NetDESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new DESCryptoServiceProvider())
{
try
{
// nested usings are fun!
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace Lidgren.Network
{
/// <summary>
/// Interface for an encryption algorithm
/// </summary>
public abstract class NetEncryption
{
/// <summary>
/// NetPeer
/// </summary>
protected NetPeer m_peer;
/// <summary>
/// Constructor
/// </summary>
public NetEncryption(NetPeer peer)
{
if (peer == null)
throw new NetException("Peer must not be null");
m_peer = peer;
}
public void SetKey(string str)
{
var bytes = System.Text.Encoding.ASCII.GetBytes(str);
SetKey(bytes, 0, bytes.Length);
}
public abstract void SetKey(byte[] data, int offset, int count);
/// <summary>
/// Encrypt an outgoing message in place
/// </summary>
public abstract bool Encrypt(NetOutgoingMessage msg);
/// <summary>
/// Decrypt an incoming message in place
/// </summary>
public abstract bool Decrypt(NetIncomingMessage msg);
}
}
+10 -149
View File
@@ -1,165 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// RC2 encryption
/// </summary>
public class NetRC2Encryption : INetEncryption
public class NetRC2Encryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetRC2Encryption()
{
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
/// <param name="key"></param>
public NetRC2Encryption(string key)
: this(key, m_keysizes[0])
public NetRC2Encryption(NetPeer peer)
: base(peer, new RC2CryptoServiceProvider())
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public NetRC2Encryption(NetPeer peer, string key)
: base(peer, new RC2CryptoServiceProvider())
{
try
{
// nested usings are fun!
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(key);
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
public NetRC2Encryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new RC2CryptoServiceProvider())
{
try
{
// nested usings are fun!
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}
@@ -1,164 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// Triple DES encryption
/// </summary>
public class NetTripleDESEncryption : INetEncryption
public class NetTripleDESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetTripleDESEncryption()
{
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(string key)
: this(key, m_keysizes[0])
public NetTripleDESEncryption(NetPeer peer)
: base(peer, new TripleDESCryptoServiceProvider())
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public NetTripleDESEncryption(NetPeer peer, string key)
: base(peer, new TripleDESCryptoServiceProvider())
{
try
{
// nested usings are fun!
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(key);
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
public NetTripleDESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new TripleDESCryptoServiceProvider())
{
try
{
// nested usings are fun!
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}
+13 -5
View File
@@ -7,22 +7,30 @@ namespace Lidgren.Network
/// <summary>
/// Example class; not very good encryption
/// </summary>
public class NetXorEncryption : INetEncryption
public class NetXorEncryption : NetEncryption
{
private byte[] m_key;
/// <summary>
/// NetXorEncryption constructor
/// </summary>
public NetXorEncryption(byte[] key)
public NetXorEncryption(NetPeer peer, byte[] key)
: base(peer)
{
m_key = key;
}
public override void SetKey(byte[] data, int offset, int count)
{
m_key = new byte[count];
Array.Copy(data, offset, m_key, 0, count);
}
/// <summary>
/// NetXorEncryption constructor
/// </summary>
public NetXorEncryption(string key)
public NetXorEncryption(NetPeer peer, string key)
: base(peer)
{
m_key = Encoding.UTF8.GetBytes(key);
}
@@ -30,7 +38,7 @@ namespace Lidgren.Network
/// <summary>
/// Encrypt an outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
public override bool Encrypt(NetOutgoingMessage msg)
{
int numBytes = msg.LengthBytes;
for (int i = 0; i < numBytes; i++)
@@ -44,7 +52,7 @@ namespace Lidgren.Network
/// <summary>
/// Decrypt an incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
public override bool Decrypt(NetIncomingMessage msg)
{
int numBytes = msg.LengthBytes;
for (int i = 0; i < numBytes; i++)
@@ -44,7 +44,8 @@ namespace Lidgren.Network
/// <summary>
/// 16 byte key
/// </summary>
public NetXtea(byte[] key, int rounds)
public NetXtea(NetPeer peer, byte[] key, int rounds)
: base(peer)
{
if (key.Length < c_keySize)
throw new NetException("Key too short!");
@@ -73,19 +74,26 @@ namespace Lidgren.Network
/// <summary>
/// 16 byte key
/// </summary>
public NetXtea(byte[] key)
: this(key, 32)
public NetXtea(NetPeer peer, byte[] key)
: this(peer, key, 32)
{
}
/// <summary>
/// String to hash for key
/// </summary>
public NetXtea(string key)
: this(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key)), 32)
public NetXtea(NetPeer peer, string key)
: this(peer, NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(key)), 32)
{
}
public override void SetKey(byte[] data, int offset, int length)
{
var key = NetUtility.ComputeSHAHash(data, offset, length);
NetException.Assert(key.Length >= 16);
SetKey(key, 0, 16);
}
/// <summary>
/// Encrypts a block of bytes
/// </summary>