/**
* Steamless - Copyright (c) 2015 - 2017 atom0s [atom0s@live.com]
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to
* Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
*
* By using Steamless, you agree to the above license and its terms.
*
* Attribution - You must give appropriate credit, provide a link to the license and indicate if changes were
* made. You must do so in any reasonable manner, but not in any way that suggests the licensor
* endorses you or your use.
*
* Non-Commercial - You may not use the material (Steamless) for commercial purposes.
*
* No-Derivatives - If you remix, transform, or build upon the material (Steamless), you may not distribute the
* modified material. You are, however, allowed to submit the modified works back to the original
* Steamless project in attempt to have it added to the original project.
*
* You may not apply legal terms or technological measures that legally restrict others
* from doing anything the license permits.
*
* No warranties are given.
*/
namespace Steamless.API.Crypto
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
public class AesHelper : IDisposable
{
///
/// Internal original key set by the user of this class.
///
private readonly byte[] m_OriginalKey;
///
/// Internal original iv set by the user of this class.
///
private readonly byte[] m_OriginalIv;
///
/// Internal AES crypto provider.
///
private AesCryptoServiceProvider m_AesCryptoProvider;
///
/// Default Constructor
///
///
///
///
///
public AesHelper(byte[] key, byte[] iv, CipherMode mode = CipherMode.ECB, PaddingMode padding = PaddingMode.None)
{
// Store the original key and iv..
this.m_OriginalKey = key;
this.m_OriginalIv = iv;
// Create the AES crypto provider..
this.m_AesCryptoProvider = new AesCryptoServiceProvider
{
Key = key,
IV = iv,
Mode = mode,
Padding = padding
};
}
///
/// Default Deconstructor
///
~AesHelper()
{
this.Dispose(false);
}
///
/// IDispose implementation.
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
///
/// IDispose implementation.
///
///
protected virtual void Dispose(bool disposing)
{
this.m_AesCryptoProvider?.Dispose();
this.m_AesCryptoProvider = null;
}
///
/// Rebuilds the current iv (or the one given).
///
///
///
public bool RebuildIv(byte[] iv = null)
{
// Use the current iv if none is set..
if (iv == null)
iv = this.m_OriginalIv;
try
{
using (var decryptor = this.m_AesCryptoProvider.CreateDecryptor())
{
return decryptor.TransformBlock(iv, 0, iv.Length, this.m_OriginalIv, 0) > 0;
}
}
catch
{
return false;
}
}
///
/// Decrypts the given data using the given mode and padding.
///
///
///
///
///
public byte[] Decrypt(byte[] data, CipherMode mode, PaddingMode padding)
{
ICryptoTransform decryptor = null;
MemoryStream mStream = null;
CryptoStream cStream = null;
try
{
// Update the mode and padding for the decryption..
this.m_AesCryptoProvider.Mode = mode;
this.m_AesCryptoProvider.Padding = padding;
// Create the decryptor..
decryptor = this.m_AesCryptoProvider.CreateDecryptor(this.m_OriginalKey, this.m_OriginalIv);
// Create a memory stream for our data..
mStream = new MemoryStream(data);
// Create the crypto stream..
cStream = new CryptoStream(mStream, decryptor, CryptoStreamMode.Read);
// Decrypt the data..
var totalBuffer = new List();
var buffer = new byte[2048];
while ((cStream.Read(buffer, 0, 2048)) > 0)
totalBuffer.AddRange(buffer);
return totalBuffer.ToArray();
}
catch
{
return null;
}
finally
{
cStream?.Dispose();
mStream?.Dispose();
decryptor?.Dispose();
}
}
}
}