public byte[] Decrypt(byte[] encrypted, byte[] secret) { using (var aesAlgorithm = new AesManaged()) { var discoveredSalt = new byte[8]; var encryptedWithSaltBytes = encrypted; var encryptedBytes = new byte[encryptedWithSaltBytes.Length - OPENSSL_SALT_PREFIX_BYTES.Length - discoveredSalt.Length]; Buffer.BlockCopy(encryptedWithSaltBytes, OPENSSL_SALT_PREFIX_BYTES.Length, discoveredSalt, 0, discoveredSalt.Length); Buffer.BlockCopy(encryptedWithSaltBytes, OPENSSL_SALT_PREFIX_BYTES.Length + discoveredSalt.Length, encryptedBytes, 0, encryptedBytes.Length); using (var deriveBytes = new OpenSslCompatDeriveBytes(secret, discoveredSalt, HASH_ALGORITHM, 1)) { var bytes = deriveBytes.GetBytes(48); byte[] key = new byte[32], iv = new byte[16]; Buffer.BlockCopy(bytes, 0, key, 0, key.Length); Buffer.BlockCopy(bytes, key.Length, iv, 0, iv.Length); aesAlgorithm.Mode = CipherMode.CBC; aesAlgorithm.KeySize = 256; aesAlgorithm.BlockSize = 128; aesAlgorithm.Padding = PaddingMode.PKCS7; aesAlgorithm.Key = key; aesAlgorithm.IV = iv; using (var decryptor = aesAlgorithm.CreateDecryptor()) { var plainTextBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); return(plainTextBytes); } } } }
public byte[] Encrypt(byte[] data, byte[] secret) { // AesManaged: native .NET, likely preferred for smaller buffers // AesCryptoServiceProvider: FIPS compliance, but probably only Windows available? // Aes.Create allows framework to choose most appropriate implementation using (var aesAlgorithm = Aes.Create()) { var saltBytes = new byte[8]; m_RngCrypto.GetNonZeroBytes(saltBytes); using (var deriveBytes = new OpenSslCompatDeriveBytes(secret, saltBytes, HASH_ALGORITHM, 1)) { var bytes = deriveBytes.GetBytes(48); byte[] key = new byte[32], iv = new byte[16]; Buffer.BlockCopy(bytes, 0, key, 0, key.Length); Buffer.BlockCopy(bytes, key.Length, iv, 0, iv.Length); aesAlgorithm.Mode = CipherMode.CBC; aesAlgorithm.KeySize = 256; aesAlgorithm.BlockSize = 128; aesAlgorithm.Padding = PaddingMode.PKCS7; aesAlgorithm.Key = key; aesAlgorithm.IV = iv; using (var encryptor = aesAlgorithm.CreateEncryptor()) { var encryptedBytes = encryptor.TransformFinalBlock(data, 0, data.Length); var encryptedWithSaltBytes = new byte[OPENSSL_SALT_PREFIX_BYTES.Length + saltBytes.Length + encryptedBytes.Length]; Buffer.BlockCopy(OPENSSL_SALT_PREFIX_BYTES, 0, encryptedWithSaltBytes, 0, OPENSSL_SALT_PREFIX_BYTES.Length); Buffer.BlockCopy(saltBytes, 0, encryptedWithSaltBytes, OPENSSL_SALT_PREFIX_BYTES.Length, saltBytes.Length); Buffer.BlockCopy(encryptedBytes, 0, encryptedWithSaltBytes, OPENSSL_SALT_PREFIX_BYTES.Length + saltBytes.Length, encryptedBytes.Length); return(encryptedWithSaltBytes); } } } }