/// <summary>Decrypt at file path</summary> /// <returns>Path to the decrypted file</returns> public FileInfo DecryptFile(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 fext = fi.Extension.TrimStart(new char[] { '.' }); // make sure valid file type if (!fext.Equals(Extension, StringComparison.InvariantCultureIgnoreCase)) { return(null); } // write to file - never overwrite using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); // 4 bytes - write a magic number - which is 'ray' followed by 0 byte[] magic = new byte[Magic.Length]; fs.Read(magic); if (!ArraysEqual(magic, Magic)) { return(null); } // 2 bytes - write the file format version which is 1.0 byte[] ver = new byte[Version.Length]; fs.Read(ver); // 16 bytes - first write the IV out which is 16 bytes byte[] iv = new byte[16]; fs.Read(iv); // 2 bytes - read a delimiator which is 01 byte[] delim = new byte[Delimiter.Length]; fs.Read(delim); // 1 byte - the length of the extension string byte[] ebl = new byte[1]; fs.Read(ebl); int el = Convert.ToInt32(ebl[0]); // read N bytes the original extension byte[] eb = new byte[el]; fs.Read(eb); string ext = Encoding.UTF8.GetString(eb); // 2 bytes - read a delimiator which is 01 fs.Read(delim); // 1 byte for the metadata size byte[] mdl = new byte[1]; fs.Read(mdl); // finally get the data itself int offset = 28 + el; byte[] data = new byte[fs.Length - offset]; fs.Read(data); // decrypt AESEncryptor enc = new AESEncryptor(); byte[] file = enc.Decrypt(data, this.Key, iv); enc.Clear(); string outPath = $"{dir}/{name}{this.Suffix}.{ext}"; File.WriteAllBytes(outPath, file); fs.Close(); return(new FileInfo(outPath)); }
/// <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)); }