Skip to content

Instantly share code, notes, and snippets.

@Dalstroem
Last active April 19, 2018 07:49
Show Gist options
  • Save Dalstroem/b39b66fd6cd6d7ba6ab9c94802bca418 to your computer and use it in GitHub Desktop.
Save Dalstroem/b39b66fd6cd6d7ba6ab9c94802bca418 to your computer and use it in GitHub Desktop.
File encryption and decryption with random salt.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace Dalstroem
{
public class Encrypter
{
private const int SaltLength = 32;
private const int Iterations = 1000;
[DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
public static extern bool ZeroMemory(IntPtr destination, int length);
private byte[] GenerateRandomSalt()
{
var data = new byte[SaltLength];
using (var rng = new RNGCryptoServiceProvider())
{
for (var i = 0; i < 10; i++)
{
rng.GetBytes(data);
}
}
return data;
}
private RijndaelManaged CreateEncryptor() => new RijndaelManaged
{
KeySize = 256,
BlockSize = 128,
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CFB
};
public byte[] Encrypt(byte[] plainBytes, string passphrase)
{
var passphraseBytes = Encoding.UTF8.GetBytes(passphrase);
var salt = GenerateRandomSalt();
using (var encryptor = CreateEncryptor())
{
using (var key = new Rfc2898DeriveBytes(passphraseBytes, salt, Iterations))
{
encryptor.Key = key.GetBytes(encryptor.KeySize / 8);
encryptor.IV = key.GetBytes(encryptor.BlockSize / 8);
}
using (var encryptedStream = new MemoryStream())
{
encryptedStream.Write(salt, 0, salt.Length);
using (var cryptoStream = new CryptoStream(encryptedStream, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
}
return encryptedStream.ToArray();
}
}
}
public byte[] Decrypt(byte[] encryptedBytes, string passphrase)
{
var passphraseBytes = Encoding.UTF8.GetBytes(passphrase);
var salt = new byte[SaltLength];
for (var i = 0; i < SaltLength; i++)
{
salt[i] = encryptedBytes[i];
}
using (var encryptor = CreateEncryptor())
{
using (var key = new Rfc2898DeriveBytes(passphraseBytes, salt, Iterations))
{
encryptor.Key = key.GetBytes(encryptor.KeySize / 8);
encryptor.IV = key.GetBytes(encryptor.BlockSize / 8);
}
using (var decryptedStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(decryptedStream, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
var length = encryptedBytes.Length - SaltLength;
cryptoStream.Write(encryptedBytes, SaltLength, length);
cryptoStream.FlushFinalBlock();
}
return decryptedStream.ToArray();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment