Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save priyankakundu/6e86abfbd7aa3bc9aaacc2462a9fb8cc to your computer and use it in GitHub Desktop.
Save priyankakundu/6e86abfbd7aa3bc9aaacc2462a9fb8cc to your computer and use it in GitHub Desktop.
C# password-based encryption helper class.
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
public class PasswordCryptoServiceProvider : IDisposable
{
protected const string Base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
private readonly SymmetricAlgorithm algorithm;
private bool disposed = false;
public PasswordCryptoServiceProvider()
: this("AES")
{ }
public PasswordCryptoServiceProvider(string alorithmName)
: this(SymmetricAlgorithm.Create(alorithmName))
{ }
public PasswordCryptoServiceProvider(SymmetricAlgorithm algorithm)
{
if (null == algorithm)
{
throw new ArgumentNullException(nameof(algorithm));
}
this.algorithm = algorithm;
this.GenerateKey();
}
public string Key { get; set; }
public byte[] Encrypt(byte[] data)
{
if (this.disposed)
{
throw new ObjectDisposedException(this.GetType().FullName);
}
// generate a new IV each time the Encrypt is called
this.algorithm.GenerateIV();
var iv = this.algorithm.IV;
using (var rgb = new Rfc2898DeriveBytes(this.Key, iv))
{
this.algorithm.Key = rgb.GetBytes(this.algorithm.KeySize / 8);
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, this.algorithm.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
}
var encryptedData = ms.ToArray();
return iv.Concat(encryptedData).ToArray();
}
}
}
public byte[] Decrypt(byte[] encryptedData)
{
if (this.disposed)
{
throw new ObjectDisposedException(this.GetType().FullName);
}
// extract parts of the encoded data
var iv = new byte[this.algorithm.BlockSize / 8];
var data = new byte[encryptedData.Length - iv.Length];
Array.Copy(encryptedData, 0, iv, 0, iv.Length);
Array.Copy(encryptedData, iv.Length, data, 0, data.Length);
using (var rgb = new Rfc2898DeriveBytes(this.Key, iv))
{
this.algorithm.Key = rgb.GetBytes(this.algorithm.KeySize / 8);
this.algorithm.IV = iv;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, this.algorithm.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
}
return ms.ToArray();
}
}
}
public void GenerateKey()
{
this.GenerateKey(this.algorithm.KeySize / 8);
}
public void GenerateKey(int length)
{
var base58Chars = PasswordCryptoServiceProvider.Base58Chars.ToCharArray();
using (var rng = new RNGCryptoServiceProvider())
{
var seed = new byte[4];
rng.GetBytes(seed);
var rnd = new Random(BitConverter.ToInt32(seed, 0));
this.Key = new string(Enumerable.Range(0, length).Select(x => base58Chars[rnd.Next(base58Chars.Length)]).ToArray());
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
if (disposing)
{
this.algorithm.Dispose();
}
this.disposed = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment