Encrypt a byte array This code is a Frankenstein. I found ten examples done in ten different ways and my requirements were slightly different so even if they were reliable they weren't a copy and paste solution.

Encrypt takes in a byte[] and password and returns the byte[] encrypted with the password. It has to tack on the length of the original byte[] and the initialization vector used by the encryption algorithm. 

Decrypt knows how to read the encrypted byte[] and will return the original message.

Note: One thing about naming conventions - Since a lot of this is copy and paste from different sources I tended to keep the original authors' conventions so that the code would match up. That's why some variables start with caps and some don't. Not looking to have this post turn into a tangent about that low hanging fruit though. But since it's obvious I thought I should point it out.

Encrypt

// https://social.msdn.microsoft.com/Forums/vstudio/en-US/eab7d698-2340-4ba0-a91c-da6fae06963c/aes-encryption-encrypting-byte-array?forum=csharpgeneral
// https://crypto.stackexchange.com/questions/2280/why-is-the-iv-passed-in-the-clear-when-it-can-be-easily-encrypted
public static byte[] Encrypt(byte[] bytesToEncrypt, string password)
{
    byte[] ivSeed = Guid.NewGuid().ToByteArray();

    var rfc = new Rfc2898DeriveBytes(password, ivSeed);
    byte[] Key = rfc.GetBytes(16);
    byte[] IV = rfc.GetBytes(16);

    byte[] encrypted;
    using (MemoryStream mstream = new MemoryStream())
    {
        using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
        {
            using (CryptoStream cryptoStream = new CryptoStream(mstream, aesProvider.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
            {
                cryptoStream.Write(bytesToEncrypt, 0, bytesToEncrypt.Length);
            }
        }
        encrypted = mstream.ToArray();
    }

    var messageLengthAs32Bits = Convert.ToInt32(bytesToEncrypt.Length);
    var messageLength = BitConverter.GetBytes(messageLengthAs32Bits);

    encrypted = encrypted.Prepend(ivSeed);
    encrypted = encrypted.Prepend(messageLength);

    return encrypted;
}


Decrypt

public static byte[] Decrypt(byte[] bytesToDecrypt, string password)
{
    (byte[] messageLengthAs32Bits, byte[] bytesWithIv) = bytesToDecrypt.Shift(4); // get the message length
    (byte[] ivSeed, byte[] encrypted) = bytesWithIv.Shift(16);                    // get the initialization vector

    var length = BitConverter.ToInt32(messageLengthAs32Bits, 0);

    var rfc = new Rfc2898DeriveBytes(password, ivSeed);
    byte[] Key = rfc.GetBytes(16);
    byte[] IV = rfc.GetBytes(16);

    byte[] decrypted;
    using (MemoryStream mStream = new MemoryStream(encrypted))
    {
        using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
        {
            aesProvider.Padding = PaddingMode.None;
            using (CryptoStream cryptoStream = new CryptoStream(mStream,aesProvider.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
            {
                cryptoStream.Read(encrypted, 0, length);
            }
        }
        decrypted = mStream.ToArray().Take(length).ToArray();
    }
    return decrypted;
}


Relevant Extension Methods (i'm more worried about security than these)

    public static byte[] Prepend(this byte[] bytes, byte[] bytesToPrepend)
    {
        var tmp = new byte[bytes.Length + bytesToPrepend.Length];
        bytesToPrepend.CopyTo(tmp, 0);
        bytes.CopyTo(tmp, bytesToPrepend.Length);
        return tmp;
    }

    public static (byte[] left, byte[] right) Shift(this byte[] bytes, int size)
    {
        var left = new byte[size];
        var right = new byte[bytes.Length - size];

        Array.Copy(bytes, 0, left, 0, left.Length);
        Array.Copy(bytes, left.Length, right, 0, right.Length);

        return (left, right);
    }
Standard disclaimer: in a production setting it is overwhelmingly better to use somebody else's crypto. 

I don't have the expertise to certify "Yes, this is secure" (and as I'm some randomer online, you should assume that even if I was actually a world expert!) There are, however, a few things that strike me as red flags.

byte[] ivSeed = Guid.NewGuid().ToByteArray();


In crypto, if you need a random number, you basically always need a cryptographically secure random number. NewGuid() is not cryptographically secure. 

var messageLength = BitConverter.GetBytes(messageLengthAs32Bits);


Block ciphers like AES do not claim to obscure the approximate message length, so this is not strictly a vulnerability. Nevertheless if you are vulnerable to any attacks based on the length, then passing the precise length in plaintext makes those attacks a whole bunch quicker and easier to execute.

byte[] Key = rfc.GetBytes(16);
byte[] IV = rfc.GetBytes(16);


The derivation of your key should not be tied to the derivation of your IV.