/trunk/WingMan/Utilities/AES.cs |
@@ -1,13 +1,13 @@ |
using System.IO; |
using System.Linq; |
using System.Security.Cryptography; |
using System.Text; |
using System.Threading.Tasks; |
|
namespace WingMan.Utilities |
{ |
public static class AES |
public static class Aes |
{ |
private const int AesKeySize = 256; |
private const int AesKeyIterations = 4096; |
private const int AesBlockSize = 128; |
private const CipherMode AesCipherMode = CipherMode.CBC; |
@@ -28,21 +28,22 @@ |
{ |
var outputStream = new MemoryStream(); |
|
using (var rijdanelManaged = new RijndaelManaged()) |
using (var aesManaged = new AesManaged()) |
{ |
// FIPS-197 / CBC |
rijdanelManaged.BlockSize = AesBlockSize; |
rijdanelManaged.Mode = AesCipherMode; |
rijdanelManaged.Padding = AesPaddingMode; |
aesManaged.BlockSize = AesBlockSize; |
aesManaged.Mode = AesCipherMode; |
aesManaged.Padding = AesPaddingMode; |
aesManaged.KeySize = AesKeySize; |
|
// Compute the salt and the IV from the key. |
var salt = new byte[AesKeySaltBytes]; |
Rng.GetBytes(salt); |
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations); |
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); |
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); |
aesManaged.Key = derivedKey.GetBytes(aesManaged.KeySize / 8); |
aesManaged.IV = derivedKey.GetBytes(aesManaged.BlockSize / 8); |
|
using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV)) |
using (var encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV)) |
{ |
using (var memoryStream = new MemoryStream()) |
{ |
@@ -76,21 +77,22 @@ |
/// <returns>an encrypted byte array</returns> |
public static async Task<byte[]> Encrypt(byte[] data, string key) |
{ |
using (var rijdanelManaged = new RijndaelManaged()) |
using (var aesManaged = new AesManaged()) |
{ |
// FIPS-197 / CBC |
rijdanelManaged.BlockSize = AesBlockSize; |
rijdanelManaged.Mode = AesCipherMode; |
rijdanelManaged.Padding = AesPaddingMode; |
aesManaged.BlockSize = AesBlockSize; |
aesManaged.Mode = AesCipherMode; |
aesManaged.Padding = AesPaddingMode; |
aesManaged.KeySize = AesKeySize; |
|
// Compute the salt and the IV from the key. |
var salt = new byte[AesKeySaltBytes]; |
Rng.GetBytes(salt); |
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations); |
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); |
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); |
aesManaged.Key = derivedKey.GetBytes(aesManaged.KeySize / 8); |
aesManaged.IV = derivedKey.GetBytes(aesManaged.BlockSize / 8); |
|
using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV)) |
using (var encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV)) |
{ |
using (var memoryStream = new MemoryStream()) |
{ |
@@ -133,19 +135,20 @@ |
//var salt = data.Take(AesKeySaltBytes).ToArray(); |
//var text = data.Skip(AesKeySaltBytes).ToArray(); |
|
using (var rijdanelManaged = new RijndaelManaged()) |
using (var aesManaged = new AesManaged()) |
{ |
// FIPS-197 / CBC |
rijdanelManaged.BlockSize = AesBlockSize; |
rijdanelManaged.Mode = AesCipherMode; |
rijdanelManaged.Padding = AesPaddingMode; |
aesManaged.BlockSize = AesBlockSize; |
aesManaged.Mode = AesCipherMode; |
aesManaged.Padding = AesPaddingMode; |
aesManaged.KeySize = AesKeySize; |
|
// Retrieve the key and the IV from the salt. |
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations); |
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); |
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); |
aesManaged.Key = derivedKey.GetBytes(aesManaged.KeySize / 8); |
aesManaged.IV = derivedKey.GetBytes(aesManaged.BlockSize / 8); |
|
using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV)) |
using (var decryptor = aesManaged.CreateDecryptor(aesManaged.Key, aesManaged.IV)) |
{ |
using (var memoryStream = new MemoryStream(text)) |
{ |
@@ -176,19 +179,20 @@ |
var salt = data.Take(AesKeySaltBytes).ToArray(); |
var text = data.Skip(AesKeySaltBytes).ToArray(); |
|
using (var rijdanelManaged = new RijndaelManaged()) |
using (var aesManaged = new AesManaged()) |
{ |
// FIPS-197 / CBC |
rijdanelManaged.BlockSize = AesBlockSize; |
rijdanelManaged.Mode = AesCipherMode; |
rijdanelManaged.Padding = AesPaddingMode; |
aesManaged.BlockSize = AesBlockSize; |
aesManaged.Mode = AesCipherMode; |
aesManaged.Padding = AesPaddingMode; |
aesManaged.KeySize = AesKeySize; |
|
// Retrieve the key and the IV from the salt. |
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations); |
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8); |
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8); |
aesManaged.Key = derivedKey.GetBytes(aesManaged.KeySize / 8); |
aesManaged.IV = derivedKey.GetBytes(aesManaged.BlockSize / 8); |
|
using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV)) |
using (var decryptor = aesManaged.CreateDecryptor(aesManaged.Key, aesManaged.IV)) |
{ |
using (var memoryStream = new MemoryStream(text)) |
{ |
@@ -208,15 +212,12 @@ |
} |
} |
|
public static string ExpandKey(string password, int size = 32) |
public static string ExpandKey(string password, int length = 32) |
{ |
var sb = new StringBuilder(password); |
do |
{ |
sb.Append(password); |
} while (sb.Length < size); |
|
return sb.ToString(0, size); |
if (length <= password.Length) return password.Substring(0, length); |
while (password.Length * 2 <= length) password += password; |
if (password.Length < length) password += password.Substring(0, length - password.Length); |
return password; |
} |
} |
} |