Is Rfc2898DeriveBytes random? C# I am trying to wrap my head around encryption in .NET. I am trying to implement a simple solution in ASP.NET Core to encrypt a cookie containing some non-meaningful numbers to outsiders. I need to be able to read the cookie content again.

This example (http://www.saipanyam.net/2010/03/encrypt-query-strings.html) uses Rfc2898DeriveBytes and RijndaelManaged but I don't understand if Rfc2898DeriveBytes is producing a random key tied to e.g. machine key or something else.

I need to be able to move software to a new server without managing machine keys, Redis or similar (just looking for something very simple to encrypt data). 

// is this random? And if so, will I be able to read cookie contents in potentially 2 years of time?
keyGenerator = new Rfc2898DeriveBytes(ENCRYPTION_KEY, SALT);
key = keyGenerator.GetBytes(32);

// entire code from link above (clean up)

public static class MyHelper
{
    private const string ENCRYPTION_KEY = "some-secret-key";

    /// The salt value used to strengthen the encryption.
    private readonly static byte[] SALT = Encoding.ASCII.GetBytes(ENCRYPTION_KEY);
    private readonly static byte[] key;
    private readonly static byte[] iv;
    private static readonly Rfc2898DeriveBytes keyGenerator;

    static MyHelper()
    {
        keyGenerator = new Rfc2898DeriveBytes(ENCRYPTION_KEY, SALT);
        key = keyGenerator.GetBytes(32);
        iv = keyGenerator.GetBytes(16);
    }

    /// Encrypts any string using the Rijndael algorithm.
    /// A Base64 encrypted string.
    public static string Encrypt(string inputText)
    {
        //Create a new RijndaelManaged cipher for the symmetric algorithm from the key and iv
        RijndaelManaged rijndaelCipher = new RijndaelManaged { Key = key, IV = iv };

        byte[] plainText = Encoding.Unicode.GetBytes(inputText);

        using (ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor())
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(plainText, 0, plainText.Length);
                    cryptoStream.FlushFinalBlock();
                    return Convert.ToBase64String(memoryStream.ToArray());
                }
            }
        }
    }

    /// Decrypts a previously encrypted string.
    /// The encrypted string to decrypt.
    public static string Decrypt(string inputText)
    {
        RijndaelManaged rijndaelCipher = new RijndaelManaged();
        byte[] encryptedData = Convert.FromBase64String(inputText);

        using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(key, iv))
        {
            using (MemoryStream memoryStream = new MemoryStream(encryptedData))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                {
                    byte[] plainText = new byte[encryptedData.Length];
                    int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
                    return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
                }
            }
        }
    }
}
No, Rfc2898DeriveBytes itself represents a deterministic algorithm. Any randomness it produces comes from a combination of randomness in the password (incorrectly named ENCRYPTION_KEY in the code) and the salt (the correctly named SALT). The other input options (such as the iteration count and string encoding) are configuration options and do not add significant randomness while still altering the final result.

Generally the output of Rfc2898DeriveBytes is made random by using a random salt which is then stored with the ciphertext (or resulting password hash, if it is used for that purpose). During decryption that same salt is used as input so that the same output key material can be produced to perform the decryption. 

There are ways of constructing a class instance in such a way that the salt is generated internally, e.g. Rfc2898DeriveBytes(String, int) where the final int is the salt size. That's however not used in the code that you've shown.



Notes:


The inaptly named Rfc2898DeriveBytes class implements PBKDF2 and therefore should have been named PBKDF2DeriveBytes or just PBKDF2.
As indicated, PBKDF2 operates on a password, not a key. You can directly use a key with a unique or random IV to encrypt ciphertext if you already have a key.
A sentence such as "just looking for something very simple to encrypt data" will make any cryptographer cringe. You either do cryptography right or you can forget about security; there is not all that much middle ground.