You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.8 KiB
130 lines
3.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace EncryptedNetwork
|
|
{
|
|
public unsafe struct AESKey
|
|
{
|
|
public const int KeySize = 32;
|
|
public const int IVSize = 16;
|
|
|
|
internal fixed byte key[KeySize];
|
|
internal fixed byte iv[IVSize];
|
|
|
|
/// <summary>
|
|
/// The Key (256 bit)
|
|
/// </summary>
|
|
public byte[] Key
|
|
{
|
|
get
|
|
{
|
|
byte[] bytes = new byte[KeySize];
|
|
fixed (byte* k = key)
|
|
{
|
|
Marshal.Copy((IntPtr)k, bytes, 0, KeySize);
|
|
}
|
|
return bytes;
|
|
}
|
|
set
|
|
{
|
|
if (value.Length != KeySize) throw new ArgumentException(nameof(value) + " must be exaclty " + KeySize + " bytes (not " + value.Length + ")");
|
|
fixed (byte* k = key)
|
|
{
|
|
Marshal.Copy(value, 0, (IntPtr)k, KeySize);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The IV (128 bits)
|
|
/// </summary>
|
|
public byte[] IV
|
|
{
|
|
get
|
|
{
|
|
byte[] bytes = new byte[IVSize];
|
|
fixed (byte* k = iv)
|
|
{
|
|
Marshal.Copy((IntPtr)k, bytes, 0, IVSize);
|
|
}
|
|
return bytes;
|
|
}
|
|
set
|
|
{
|
|
if (value.Length != IVSize) throw new ArgumentException(nameof(value) + " must be exaclty " + IVSize + " bytes (not " + value.Length + ")");
|
|
fixed (byte* k = iv)
|
|
{
|
|
Marshal.Copy(value, 0, (IntPtr)k, IVSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Binary serialisation of this key
|
|
/// </summary>
|
|
public byte[] BinaryData
|
|
{
|
|
get
|
|
{
|
|
return this.ToByteArrayUnmanaged();
|
|
}
|
|
set
|
|
{
|
|
if (value.Length < sizeof(AESKey)) throw new ArgumentException(nameof(value) + " must be at least " + sizeof(AESKey) + " bytes (not " + value.Length + ")");
|
|
fixed (AESKey* k = &this)
|
|
{
|
|
Marshal.Copy(value, 0, (IntPtr)k, sizeof(AESKey));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new key
|
|
/// </summary>
|
|
/// <returns>The new AES Key</returns>
|
|
public static AESKey NewKey()
|
|
{
|
|
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
|
|
byte[] buffer = new byte[sizeof(AESKey)];
|
|
rng.GetBytes(buffer);
|
|
rng.Dispose();
|
|
return buffer.ToStructureUnmanaged<AESKey>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the key and iv to an AesCryptoServiceProvider
|
|
/// </summary>
|
|
/// <param name="r">The CSP</param>
|
|
public void ToCSP(AesCryptoServiceProvider r)
|
|
{
|
|
r.KeySize = 256;
|
|
r.BlockSize = 128;
|
|
|
|
r.Key = Key;
|
|
r.IV = IV;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the key and iv from and AESCryptoServiceProvider
|
|
/// </summary>
|
|
/// <param name="r">The CSP</param>
|
|
public void FromCSP(AesCryptoServiceProvider r)
|
|
{
|
|
Key = r.Key;
|
|
IV = r.IV;
|
|
}
|
|
/// <summary>
|
|
/// Initialise a new AESKey from an AESCryptoServiceProvider
|
|
/// </summary>
|
|
/// <param name="aes">The AES key</param>
|
|
public AESKey(AesCryptoServiceProvider aes)
|
|
{
|
|
FromCSP(aes);
|
|
}
|
|
}
|
|
}
|