public void EncryptFileTest()
        {
            string path = $"{IOHelpers.DesktopPath}/test.jpeg";

            // get a handle to the file
            FileInfo fi = new FileInfo(path);

            if (!fi.Exists)
            {
                Assert.Fail("No file to test");
                return;
            }

            // base file name
            string name = Path.GetFileNameWithoutExtension(fi.Name);
            string ext  = fi.Extension.TrimStart(new char[] { '.' });

            // 4.2 Gig limit or throws an exception
            byte[] data = File.ReadAllBytes(path);

            // encrypt
            AESEncryptor  enc     = new AESEncryptor();
            CipherMessage results = enc.Encrypt(data, key);

            // write to file - never overwrite
            using FileStream fs = new FileStream($"{IOHelpers.DesktopPath}/{name}.rayx", FileMode.CreateNew, FileAccess.Write);

            // 4 bytes - write a magic number - which is 'ray' followed by 0
            fs.Write(new byte[] { 0x72, 0x61, 0x79, 0x00 });

            // 2 bytes - write the file format version which is 1.0
            fs.Write(new byte[] { 0x01, 0x00 });

            // 16 bytes - first write the IV out which is 16 bytes
            fs.Write(results.IV, 0, results.IV.Length);

            // 2 bytes - write a delimiator which is 01
            fs.Write(new byte[] { 0x00, 0x01 });

            // write the original extension which is 1+len
            byte[] eb  = Encoding.UTF8.GetBytes(ext);
            byte[] ebl = BitConverter.GetBytes(eb.Length);
            fs.WriteByte(ebl[0]);
            fs.Write(eb);

            // 2 bytes - write a delimiator which is 01
            fs.Write(new byte[] { 0x00, 0x01 });

            // write the encrypted data
            fs.Write(results.CipherBytes, 0, results.CipherBytes.Length);

            // flush and close
            fs.Flush();
            fs.Close();

            Assert.IsTrue(results.CipherBytes.Length > 0);
        }
        /// <summary>Encrypt the file at file path</summary>
        /// <returns>Path to the newly encrypted file</returns>
        public FileInfo EncryptFile(string path)
        {
            if (String.IsNullOrWhiteSpace(path))
            {
                return(null);
            }

            // get a handle to the file
            FileInfo fi = new FileInfo(path);

            if (!fi.Exists)
            {
                return(null);
            }

            // base file name
            string dir  = fi.DirectoryName;
            string name = Path.GetFileNameWithoutExtension(fi.Name);
            string ext  = fi.Extension.TrimStart(new char[] { '.' });

            // 4.2 Gig limit or throws an exception
            byte[] data = File.ReadAllBytes(path);

            // encrypt
            AESEncryptor  enc     = new AESEncryptor();
            CipherMessage results = enc.Encrypt(data, this.Key);

            // remove the orginal from memory
            enc.Clear();

            // write to file - never overwrite
            string outPath = $"{dir}/{name}.{Extension}";

            using FileStream fs = new FileStream(outPath, FileMode.CreateNew, FileAccess.Write);

            // 4 bytes - write a magic number - which is 'ray' followed by 0
            fs.Write(Magic);

            // 2 bytes - write the file format version which is 1.0
            fs.Write(Version);

            // 16 bytes - first write the IV out which is 16 bytes
            fs.Write(results.IV, 0, results.IV.Length);

            // 2 bytes - write a delimiator which is 01
            fs.Write(Delimiter);

            // write the original extension which is 1+len
            byte[] eb  = Encoding.UTF8.GetBytes(ext);
            byte[] ebl = BitConverter.GetBytes(eb.Length);
            fs.WriteByte(ebl[0]);
            fs.Write(eb);

            // 2 bytes - write a delimiator which is 01
            fs.Write(Delimiter);

            // 1 byte - later add a metadata section of optional data but for now its just 1 byte of value 0
            fs.WriteByte(0x00);

            // write the encrypted data
            fs.Write(results.CipherBytes, 0, results.CipherBytes.Length);

            // flush and close
            fs.Flush();
            fs.Close();

            return(new FileInfo(outPath));
        }