示例#1
0
 public bool isPackage(string path, keyIterator key)
 {
     if (!MainClass.isFile(path))
     {
         if (debug)
         {
             Console.WriteLine("{0} is not a file", path);
         }
         return(false);
     }
     using (FileStream inFile = new FileStream(path, FileMode.Open))
     {
         byte[] check    = new byte[64];
         byte[] checksum = new byte[64];
         for (int i = 0; i < 64; i++)
         {
             check[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
         }
         for (int i = 0; i < 64; i++)
         {
             checksum[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
         }
         check = SHA512.Create().ComputeHash(check);
         key.resetKey();
         if (!check.SequenceEqual(checksum))
         {
             if (debug)
             {
                 Console.WriteLine("{0} failed checksum test", path);
             }
             return(false);
         }
         return(true);
     }
 }
示例#2
0
        public void encrypt(keyIterator key)
        {
            foreach (String path in fullNames)
            {
                if (debug)
                {
                    sw.Start();
                }
                //first, get the file's name
                String name = Path.GetFileName(path);
                Console.WriteLine("Encrypting " + path);
                //we also need the bytes of the name
                byte[] nameBytes  = Encoding.Unicode.GetBytes(name);
                byte   lengthByte = (byte)nameBytes.Length;               //Should always be sub 255, most of the time
                if (debug)
                {
                    Console.WriteLine("Name Length is: {0}", lengthByte);
                }
                //generate a byte for the amount of salt that is to be produced
                byte saltByte = 0;
                //Kind of random? It's close enough for this
                foreach (byte b in nameBytes)
                {
                    saltByte = (byte)(saltByte ^ b);
                }
                if (debug)
                {
                    Console.WriteLine("Salt Byte is {0}", saltByte);
                }

                var salter = new RNGCryptoServiceProvider();

                int    prefixLength = saltByte % 16;
                byte[] prefix       = new byte[prefixLength];
                salter.GetNonZeroBytes(prefix);

                int    suffixLength = ((saltByte - (saltByte % 16)) / 16);
                byte[] suffix       = new byte[suffixLength];
                salter.GetNonZeroBytes(suffix);
                if (debug)
                {
                    Console.WriteLine("Prefix and Suffix lengths: {0}, {1}", prefixLength, suffixLength);
                }

                //Put the salt on the ends of the name
                List <byte> saltedName = new List <byte>();
                for (int i = 0; i < prefixLength; i++)
                {
                    saltedName.Add(prefix[i]);
                }
                saltedName.AddRange(nameBytes);
                for (int i = 0; i < suffixLength; i++)
                {
                    saltedName.Add(suffix[i]);
                }
                if (debug)
                {
                    Console.WriteLine("Length of salted name is: " + saltedName.Count);
                }

                //Start putting together the new file
                MD5    nameGen = MD5.Create();
                String outName = BitConverter.ToString(nameGen.ComputeHash(nameBytes)).Replace("-", "").ToLower();

                //Create the "header" and write it
                List <byte> headerBytes = new List <byte>();
                headerBytes.Add(lengthByte);
                headerBytes.Add(saltByte);
                headerBytes.AddRange(saltedName.ToArray());

                if (debug)
                {
                    Console.WriteLine(("Writing to: " + Path.GetDirectoryName(path) + "\\" + outName + "\n"));
                }

                using (FileStream outFile = File.Open((Path.GetDirectoryName(path) + "\\" + outName), FileMode.Append, FileAccess.Write))
                {
                    foreach (byte b in headerBytes)
                    {
                        outFile.WriteByte((byte)(b ^ key.getKeyByte()));
                    }
                    //Write in the rest of the file, byte by byte
                    using (FileStream inFile = File.Open(path, FileMode.Open, FileAccess.Read))
                    {
                        FileInfo inFileSize = new FileInfo(path);
                        for (int i = 0; i < inFileSize.Length; i++)
                        {
                            outFile.WriteByte((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                        }
                    }
                }

                File.Delete(path);
                key.resetKey();
                if (debug)
                {
                    sw.Stop();
                    Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                    sw.Reset();
                }
            }
        }
示例#3
0
        public void decrypt(keyIterator key)
        {
            foreach (String path in fullNames)
            {
                if (debug)
                {
                    sw.Start();
                }
                Console.WriteLine("Decrypting {0}", path);

                using (FileStream inFile = File.Open(path, FileMode.Open, FileAccess.Read))
                {
                    String      outName  = "";
                    List <byte> decBytes = new List <byte>();
                    //get the name length
                    int nameLength = inFile.ReadByte() ^ key.getKeyByte();
                    if (debug)
                    {
                        Console.WriteLine("Length of file name is: {0}", nameLength);
                    }

                    //get the name out of the file
                    List <byte> byteNameRaw = new List <byte>();
                    List <byte> byteName    = new List <byte>();
                    int         saltStuff   = inFile.ReadByte() ^ key.getKeyByte();

                    if (debug)
                    {
                        Console.WriteLine("Salt Byte is {0}", saltStuff);
                    }

                    int prefixLength = saltStuff % 16;
                    int suffixLength = (saltStuff - (saltStuff % 16)) / 16;

                    if (debug)
                    {
                        Console.WriteLine("Prefix and Suffix lengths: {0}, {1}", prefixLength, suffixLength);
                    }

                    for (int i = 0; i < nameLength + prefixLength + suffixLength; i++)
                    {
                        byteNameRaw.Add((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                    }

                    //take only the filename out
                    for (int i = 0; i < nameLength; i++)
                    {
                        byteName.Add(byteNameRaw[i + prefixLength]);
                    }
                    outName = Encoding.Unicode.GetString(byteName.ToArray());

                    if (debug)
                    {
                        Console.WriteLine("Extracted name is: {0}", outName);
                    }

                    //now get the rest of the file
                    if (debug)
                    {
                        Console.WriteLine(("Writing to: " + Path.GetDirectoryName(path) + "\\" + outName + "\n"));
                    }
                    using (FileStream outFile = File.Open((Path.GetDirectoryName(path) + "\\" + outName), FileMode.Append))
                    {
                        FileInfo inFileSize = new FileInfo(path);
                        for (int i = 2 + prefixLength + nameLength + suffixLength; i < inFileSize.Length; i++)                        //fileToDecrypt.Length; i++)
                        {
                            outFile.WriteByte((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                        }
                    }
                }
                File.Delete(path);
                key.resetKey();
                if (debug)
                {
                    sw.Stop();
                    Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                    sw.Reset();
                }
            }
        }
示例#4
0
        public void listPackage(keyIterator key, string path)
        {
            root = new DirectoryInfo(Path.GetDirectoryName(root.FullName));

            Int64 fileIndex = 0;

            if (debug)
            {
                sw.Start();
            }

            using (FileStream inFile = File.Open(path, FileMode.Open, FileAccess.Read))
            {
                Int64 packSize = inFile.Length;

                //read in the checksum and compare
                byte[] check    = new byte[64];
                byte[] checksum = new byte[64];
                for (int i = 0; i < 64; i++)
                {
                    check[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                }
                for (int i = 0; i < 64; i++)
                {
                    checksum[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                }
                check = SHA512.Create().ComputeHash(check);

                if (!check.SequenceEqual(checksum))
                {
                    Console.WriteLine("File {0} is not an encrypted file, or an incorrect key has been selected.", path);
                    return;
                }
                else
                {
                    Console.WriteLine("Listing {0}", path);
                }
                fileIndex += 128;

                while (fileIndex < packSize)
                {
                    string      outName  = "";
                    List <byte> decBytes = new List <byte>();
                    //get the name length

                    /*
                     * Uint16 namelength | byte saltByteP | byte saltByteS | string saltedName (up to 260 chars + 512 salt) | Uint32 fileSize | byte[] file |   <repeats>
                     *         2         |        1       |        1       |                 up to 772                      |        4        |   up to 4GB | = 780 bytes
                     */

                    //int nameLength = (int)(inFile.ReadByte() ^ key.getKeyByte());
                    byte[] nameLengthBytes = new byte[2];
                    for (int i = 0; i < 2; i++)
                    {
                        nameLengthBytes[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                    }
                    fileIndex += 2;

                    UInt16 nameLength = BitConverter.ToUInt16(nameLengthBytes, 0);

                    if (debug)
                    {
                        Console.WriteLine("Length of file name is: {0}", nameLength);
                    }

                    //get the name out of the file
                    List <byte> byteNameRaw  = new List <byte>();
                    List <byte> byteName     = new List <byte>();
                    int         prefixLength = (inFile.ReadByte() ^ key.getKeyByte());
                    int         suffixLength = (inFile.ReadByte() ^ key.getKeyByte());
                    fileIndex += 2;

                    if (debug)
                    {
                        Console.WriteLine("Prefix and Suffix lengths: {0}, {1}", prefixLength, suffixLength);
                    }

                    for (int i = 0; i < nameLength + prefixLength + suffixLength; i++)
                    {
                        byteNameRaw.Add((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                    }
                    fileIndex += nameLength + prefixLength + suffixLength;

                    //take only the filename out
                    for (int i = 0; i < nameLength; i++)
                    {
                        byteName.Add(byteNameRaw[i + prefixLength]);
                    }
                    outName = Encoding.Unicode.GetString(byteName.ToArray());

                    byte[] fileSizeBytes = new byte[4];
                    for (int i = 0; i < 4; i++)
                    {
                        fileSizeBytes[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                    }
                    fileIndex += 4;
                    UInt32 inFileSize = BitConverter.ToUInt32(fileSizeBytes, 0);

                    Console.WriteLine("{0}: {1}", outName, MainClass.BytesToString(inFileSize));

                    //Attempt to create directory, just to be sure
                    //Directory.CreateDirectory(Path.GetDirectoryName(root + "\\" + outName));
                    //now get the rest of the file
                    inFile.Position += inFileSize;
                    key.incrementBy(inFileSize);
                    fileIndex += inFileSize;
                }
            }
            //File.Delete(path);

            if (debug)
            {
                sw.Stop();
                Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                sw.Reset();
            }
            key.resetKey();
        }
示例#5
0
        public void appendPackage(keyIterator key, string path, string toAdd = null)
        {
            walkDirectory();
            //scan all the files in the directory and find packages
            List <string> packages   = new List <string>();
            List <string> files      = new List <string>();
            int           input      = -1;
            bool          addingFile = false;

            if (!MainClass.isFile(toAdd))
            {
                addingFile = true;                 //This will eventually just direct to the file version
            }

            foreach (string s in fullNames)
            {
                if (debug)
                {
                    Console.WriteLine(s);
                }
                if (isPackage(s, key))
                {
                    if (debug)
                    {
                        Console.WriteLine("Package found: {0}", s);
                    }
                    packages.Add(s);
                }
            }
            if (debug)
            {
                Console.WriteLine("Packages added");
            }
            //if there is only one package, proceed
            //if there is more than one, prompt the user to select one
            if (packages.Count > 1)
            {
                Console.WriteLine("Found multiple packages:");
                int i = 0;
                foreach (string package in packages)
                {
                    i += 1;
                    Console.WriteLine("{0} -> {1}", i, package);
                }
                Console.Write("Select package number to use (or 0 to exit): ");
                while (input != 0 && (input < packages.Count && input != 0))
                {
                    input = -1;
                    input = Console.Read() - 48;                     //Changes input into the appropriate number
                    if (input > packages.Count || input < 0)
                    {
                        if (debug)
                        {
                            Console.WriteLine("Selected package: {0}", input);
                        }
                        Console.Write("Invalid input, please enter a number between 1 and {0}, or 0 to exit: ", packages.Count);
                    }
                }
            }
            else
            {
                input = 1;
            }
            if (debug)
            {
                Console.WriteLine("Selected package: {0}", input);
            }
            if (input == 0)
            {
                return;
            }
            string selectedPackage = packages[input - 1];

            //check toAdd, if it's null, prompt if ok to add all files in root
            if (toAdd.Equals(null))
            {
                Console.Write("No specific addition selected, ok to add all files in {0} (Y/n)?: ", path);
                while (Convert.ToChar(input) != 'Y' && Convert.ToChar(input) != 'n')
                {
                    input = Console.Read();
                    if (Convert.ToChar(input) != 'Y' && Convert.ToChar(input) != 'n')
                    {
                        Console.Write("Invalid input, please enter Y or n: ");
                    }
                }
                if (Convert.ToChar(input) == 'n')
                {
                    return;
                }
                toAdd = root.FullName;
            }
            //if it's a directory, add all files in that directory
            //if it's a file, add that file
            if (MainClass.isFile(toAdd))
            {
                files.Add(toAdd);                 //This will eventually just direct to the file version
            }
            else
            {
                files.AddRange(directoryBase.getFiles(new DirectoryInfo(toAdd)));
            }

            if (debug)
            {
                Console.WriteLine("Adding Directory: {0}", toAdd);
                Console.WriteLine("Files to add to archive:");
                foreach (string s in files)
                {
                    Console.WriteLine("{0}", s);
                }
            }

            //open the package, seek to the end
            using (FileStream package = new FileStream(selectedPackage, FileMode.Append))
            {
                var salter = new RNGCryptoServiceProvider();
                //iterate key by the file size
                key.incrementBy(package.Length);
                //encrypt the file and appends all the bytes of the result to the end

                /*
                 * This bit should also probably be externalized
                 */

                foreach (string filePath in files)
                {
                    if (debug)
                    {
                        Console.WriteLine("Adding file: {0}", filePath);
                    }
                    int retryMax = 3;
                    while (retryMax > 0)
                    {
                        try
                        {
                            using (FileStream inFile = File.Open(filePath, FileMode.Open, FileAccess.Read))
                            {
                                if (debug)
                                {
                                    sw.Start();
                                }
                                //first, get the file's name
                                string name = filePath.Substring(root.FullName.Length + 1);                                 //get the relative path
                                Console.WriteLine("Encrypting " + name);
                                //we also need the bytes of the name
                                byte[] nameBytes  = Encoding.Unicode.GetBytes(name);
                                UInt16 nameLength = (UInt16)nameBytes.Length;                                 //Should always be sub 255, most of the time
                                if (debug)
                                {
                                    Console.WriteLine("Name Length is: {0}", nameLength);
                                }
                                //generate a byte for the amount of salt that is to be produced
                                byte saltByteP = 0, saltByteS = 255;
                                //Kind of random? It's close enough for this
                                foreach (byte b in nameBytes)
                                {
                                    saltByteP = (byte)(saltByteP ^ b);
                                    saltByteS = (byte)(saltByteS ^ b);
                                }
                                if (debug)
                                {
                                    Console.WriteLine("Salt Bytes are {0}, {1}", saltByteP, saltByteS);
                                }

                                byte[] prefix = new byte[saltByteP];
                                salter.GetNonZeroBytes(prefix);

                                byte[] suffix = new byte[saltByteS];
                                salter.GetNonZeroBytes(suffix);

                                //Put the salt on the ends of the name
                                List <byte> saltedName = new List <byte>();
                                for (int i = 0; i < saltByteP; i++)
                                {
                                    saltedName.Add(prefix[i]);
                                }
                                saltedName.AddRange(nameBytes);
                                for (int i = 0; i < saltByteS; i++)
                                {
                                    saltedName.Add(suffix[i]);
                                }
                                if (debug)
                                {
                                    Console.WriteLine("Length of salted name is: " + saltedName.Count);
                                }
                                //get the length of the file as Uint32
                                UInt32 fileSize = (UInt32)(new FileInfo(filePath)).Length;

                                //Create the "header" and write it
                                List <byte> headerBytes = new List <byte>();
                                headerBytes.AddRange(BitConverter.GetBytes(nameLength));
                                headerBytes.Add(saltByteP);
                                headerBytes.Add(saltByteS);
                                headerBytes.AddRange(saltedName.ToArray());
                                headerBytes.AddRange(BitConverter.GetBytes(fileSize));

                                /*
                                 * Uint16 namelength | byte saltByteP | byte saltByteS | string saltedName (up to 260 chars + 512 salt) | Uint32 fileSize | byte[] file |   <repeats>
                                 *         2         |        1       |        1       |                 up to 772                      |        4        |   up to 4GB | = 780 bytes
                                 */

                                //if (this.debug) Console.WriteLine(("Writing to: " + Path.GetDirectoryName(path) + "\\" + outName + "\n"));

                                foreach (byte b in headerBytes)
                                {
                                    package.WriteByte((byte)(b ^ key.getKeyByte()));
                                }
                                //Write in the rest of the file, byte by byte
                                if (debug)
                                {
                                    Console.WriteLine("Reading: {0}\\{1}", root.FullName, name);
                                }

                                //FileInfo inFileSize = new FileInfo(path);
                                for (int i = 0; i < fileSize; i++)
                                {
                                    package.WriteByte((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                                }
                            }
                            if (debug)
                            {
                                Console.WriteLine("Done!\n");
                            }

                            File.Delete(filePath);
                            //key.resetKey();
                            if (debug)
                            {
                                sw.Stop();
                                Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                                sw.Reset();
                            }
                            break;                             //exit the inner retry loop
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Could not encrypt: {0}, reason: {1}", filePath, e.Message);
                            if (retryMax == 0)
                            {
                                Console.WriteLine("Failed to encrypt file: {0}", filePath);
                                Console.ReadKey();
                            }
                            else
                            {
                                Console.WriteLine("Retrying in 3 seconds...");
                                retryMax -= 1;
                                System.Threading.Thread.Sleep(3000);
                            }
                        }
                    }
                    if (!addingFile)
                    {
                        cleanRoot();
                    }
                }
            }
        }
示例#6
0
        public void encrypt(keyIterator key)
        {
            MD5 nameGen = MD5.Create();
            //This is really yuge so I split it up
            List <byte> hashInfo = new List <byte>();

            foreach (string s in fullNames)
            {
                hashInfo.AddRange(Encoding.Unicode.GetBytes(s));
            }
            foreach (string s in fullDirs)
            {
                hashInfo.AddRange(Encoding.Unicode.GetBytes(s));
            }
            string outName =
                DateTime.Today.ToString("d").Replace(@"/", "-") +
                "-" +
                BitConverter.ToString(
                    nameGen.ComputeHash(
                        hashInfo.ToArray()
                        )
                    ).Replace("-", "").ToLower().Substring(0, 10);

            Console.WriteLine("Writing to pack: {0}\\{1}", root.FullName, outName);
            using (FileStream outFile = File.Open((root.FullName + "\\" + outName), FileMode.Append, FileAccess.Write))
            {
                var    salter = new RNGCryptoServiceProvider();
                byte[] check  = new byte[64];
                salter.GetNonZeroBytes(check);
                byte[] checksum = SHA512.Create().ComputeHash(check);

                for (int i = 0; i < 64; i++)
                {
                    //Console.Write("{0} ", check[i]);
                    outFile.WriteByte((byte)(check[i] ^ key.getKeyByte()));
                }

                for (int i = 0; i < 64; i++)
                {
                    //Console.Write("{0} ", checksum[i]);
                    outFile.WriteByte((byte)(checksum[i] ^ key.getKeyByte()));
                }

                foreach (string path in fullNames)
                {
                    //Possibly replace this lock with a custom function that waits until the file is accessible or a certain amount of time has passed
                    int retryMax = 3;
                    while (retryMax > 0)
                    {
                        try
                        {
                            using (FileStream inFile = File.Open(path, FileMode.Open, FileAccess.Read))
                            {
                                if (debug)
                                {
                                    sw.Start();
                                }
                                //first, get the file's name
                                string name = path.Substring(root.FullName.Length + 1);                                 //get the relative path
                                Console.WriteLine("Encrypting " + name);
                                //we also need the bytes of the name
                                byte[] nameBytes  = Encoding.Unicode.GetBytes(name);
                                UInt16 nameLength = (UInt16)nameBytes.Length;                                 //Should always be sub 255, most of the time
                                if (debug)
                                {
                                    Console.WriteLine("Name Length is: {0}", nameLength);
                                }
                                //generate a byte for the amount of salt that is to be produced
                                byte saltByteP = 0, saltByteS = 255;
                                //Kind of random? It's close enough for this
                                foreach (byte b in nameBytes)
                                {
                                    saltByteP = (byte)(saltByteP ^ b);
                                    saltByteS = (byte)(saltByteS ^ b);
                                }
                                if (debug)
                                {
                                    Console.WriteLine("Salt Bytes are {0}, {1}", saltByteP, saltByteS);
                                }

                                byte[] prefix = new byte[saltByteP];
                                salter.GetNonZeroBytes(prefix);

                                byte[] suffix = new byte[saltByteS];
                                salter.GetNonZeroBytes(suffix);

                                //Put the salt on the ends of the name
                                List <byte> saltedName = new List <byte>();
                                for (int i = 0; i < saltByteP; i++)
                                {
                                    saltedName.Add(prefix[i]);
                                }
                                saltedName.AddRange(nameBytes);
                                for (int i = 0; i < saltByteS; i++)
                                {
                                    saltedName.Add(suffix[i]);
                                }
                                if (debug)
                                {
                                    Console.WriteLine("Length of salted name is: " + saltedName.Count);
                                }
                                //get the length of the file as Uint32
                                UInt32 fileSize = (UInt32)(new FileInfo(path)).Length;

                                //Create the "header" and write it
                                List <byte> headerBytes = new List <byte>();
                                headerBytes.AddRange(BitConverter.GetBytes(nameLength));
                                headerBytes.Add(saltByteP);
                                headerBytes.Add(saltByteS);
                                headerBytes.AddRange(saltedName.ToArray());
                                headerBytes.AddRange(BitConverter.GetBytes(fileSize));

                                /*
                                 * Uint16 namelength | byte saltByteP | byte saltByteS | string saltedName (up to 260 chars + 512 salt) | Uint32 fileSize | byte[] file |   <repeats>
                                 *         2         |        1       |        1       |                 up to 772                      |        4        |   up to 4GB | = 780 bytes
                                 */

                                //if (this.debug) Console.WriteLine(("Writing to: " + Path.GetDirectoryName(path) + "\\" + outName + "\n"));

                                foreach (byte b in headerBytes)
                                {
                                    outFile.WriteByte((byte)(b ^ key.getKeyByte()));
                                }
                                //Write in the rest of the file, byte by byte
                                if (debug)
                                {
                                    Console.WriteLine("Reading: {0}\\{1}", root.FullName, name);
                                }

                                //FileInfo inFileSize = new FileInfo(path);
                                for (int i = 0; i < fileSize; i++)
                                {
                                    outFile.WriteByte((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                                }
                            }
                            if (debug)
                            {
                                Console.WriteLine("Done!\n");
                            }

                            File.Delete(path);
                            //key.resetKey();
                            if (debug)
                            {
                                sw.Stop();
                                Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                                sw.Reset();
                            }
                            break;                             //exit the inner retry loop
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Could not encrypt: {0}, reason: {1}", path, e.Message);
                            if (retryMax == 0)
                            {
                                Console.WriteLine("Failed to encrypt file: {0}", path);
                                Console.ReadKey();
                            }
                            else
                            {
                                Console.WriteLine("Retrying in 3 seconds...");
                                retryMax -= 1;
                                System.Threading.Thread.Sleep(3000);
                            }
                        }
                    }
                }
            }
            cleanRoot();
        }
示例#7
0
        public static void Main(string[] args)
        {
            //First arg is always the executable name
            String[] cliargs     = Environment.GetCommandLineArgs();
            String   hashPath    = null;
            String   encPath     = null;
            String   command     = null;
            String   appendPath  = null;
            bool     debugLog    = false;
            bool     decryptFile = false;

            if (cliargs.Length == 4)
            {
                command = cliargs[1];
                if (Path.IsPathRooted(cliargs[2]))
                {
                    hashPath = cliargs[2];
                }
                else
                {
                    hashPath = Directory.GetCurrentDirectory() + "\\" + cliargs[2];
                }

                if (Path.IsPathRooted(cliargs[3]))
                {
                    encPath = cliargs[3];
                }
                else
                {
                    encPath = Directory.GetCurrentDirectory() + "\\" + cliargs[3];
                }
            }
            else if (cliargs.Length > 4)
            {
                command = cliargs[1];
                if (Path.IsPathRooted(cliargs[2]))
                {
                    hashPath = cliargs[2];
                }
                else
                {
                    hashPath = Directory.GetCurrentDirectory() + "\\" + cliargs[2];
                }

                if (Path.IsPathRooted(cliargs[3]))
                {
                    encPath = cliargs[3];
                }
                else
                {
                    encPath = Directory.GetCurrentDirectory() + "\\" + cliargs[3];
                }
                //----------------------
                if (!command.Equals("-a"))
                {
                    debugLog = true;
                }
                else
                {
                    if (Path.IsPathRooted(cliargs[4]))
                    {
                        appendPath = cliargs[4];
                    }
                    else
                    {
                        appendPath = Directory.GetCurrentDirectory() + "\\" + cliargs[4];
                    }
                }
            }
            else
            {
                Console.WriteLine("Not enough args.");
                Environment.Exit(-1);                 //failure
            }
            //Console.WriteLine("Hash Path: {0}\nTarget Path: {1}", hashPath, encPath);
            Console.Write("\n");
            directoryHasher hasher = new directoryHasher(new DirectoryInfo(hashPath));
            //d.walkDirectory(); //create both the hash and a list of filenames in the hash

            /*
             * Console.WriteLine(d.getDirNames());
             * foreach (string s in d.getDirNames())
             * {
             *      Console.WriteLine(s);
             * }
             */

            keyIterator key = new keyIterator(hasher.createHash());

            //key.resetKey();

            if (isFile(encPath))
            {
                decryptFile = true;
            }



            if (command.Equals("-e"))
            {
                //Console.WriteLine("Encryption mode");
                directoryPacker packer = new directoryPacker(new DirectoryInfo(encPath), debugLog);                //new directoryEncrypter(new System.IO.DirectoryInfo(encPath), debugLog);
                packer.walkDirectory();
                packer.encrypt(key);
            }
            else if (command.Equals("-d"))
            {
                //Console.WriteLine("Decryption mode");
                if (!decryptFile)
                {
                    //Console.WriteLine("Directory Mode");
                    directoryUnpacker unpacker = new directoryUnpacker(new DirectoryInfo(encPath), debugLog);
                    unpacker.walkDirectory();
                    unpacker.decrypt(key);
                }
                else
                {
                    //Console.WriteLine("File Mode");
                    directoryUnpacker unpacker = new directoryUnpacker(new DirectoryInfo(encPath), debugLog);
                    //no walk needed
                    unpacker.decryptSingle(key, encPath);
                }
            }
            else if (command.Equals("-l"))
            {
                //Console.WriteLine("List Mode");
                if (decryptFile)
                {
                    //Console.WriteLine("Listing contents of package: {0}", encPath);
                    packageManipulator manipulator = new packageManipulator(new DirectoryInfo(encPath), debugLog);                    //new directoryEncrypter(new System.IO.DirectoryInfo(encPath), debugLog);
                    //e.walkDirectory();
                    manipulator.listPackage(key, encPath);
                }
                else
                {
                    Console.WriteLine("No Package Selected");
                }
            }
            else if (command.Equals("-a"))
            {
                if (!isFile(appendPath))
                {
                    Console.WriteLine("CURRENTLY CANNOT APPEND DIRECTORY");
                }
                Console.WriteLine("WARNING: NO SAFETIES CURRENTLY IN PLACE TO PREVENT PACKAGE CORRUPTION");
                packageManipulator manipulator = new packageManipulator(new DirectoryInfo(encPath), true);
                manipulator.appendPackage(key, encPath, appendPath);
            }
            else
            {
                Console.WriteLine("Invalid command '{0}'", command);
                Environment.Exit(-1);
            }
            Console.WriteLine("Finished!");
        }
示例#8
0
        public void decrypt(keyIterator key)
        {
            /*
             * Add in a check to make sure this is actually decrypting a real encrypted file
             *
             */
            foreach (string path in fullNames)             //should only ever be one, hopefully
            {
                Int64 fileIndex = 0;
                if (debug)
                {
                    sw.Start();
                }

                using (FileStream inFile = File.Open(path, FileMode.Open, FileAccess.Read))
                {
                    Int64 packSize = inFile.Length;

                    //read in the checksum and compare
                    byte[] check    = new byte[64];
                    byte[] checksum = new byte[64];
                    for (int i = 0; i < 64; i++)
                    {
                        check[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                    }
                    for (int i = 0; i < 64; i++)
                    {
                        checksum[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                    }
                    check = SHA512.Create().ComputeHash(check);

                    if (!check.SequenceEqual(checksum))
                    {
                        Console.WriteLine("File {0} is not an encrypted file, or an incorrect key has been selected.", path);
                        continue;
                    }
                    else
                    {
                        Console.WriteLine("Decrypting {0}", path);
                    }
                    fileIndex += 128;

                    while (fileIndex < packSize)
                    {
                        string      outName  = "";
                        List <byte> decBytes = new List <byte>();
                        //get the name length

                        /*
                         * Uint16 namelength | byte saltByteP | byte saltByteS | string saltedName (up to 260 chars + 512 salt) | Uint32 fileSize | byte[] file |   <repeats>
                         *         2         |        1       |        1       |                 up to 772                      |        4        |   up to 4GB | = 780 bytes
                         */

                        //int nameLength = (int)(inFile.ReadByte() ^ key.getKeyByte());
                        byte[] nameLengthBytes = new byte[2];
                        for (int i = 0; i < 2; i++)
                        {
                            nameLengthBytes[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                        }
                        fileIndex += 2;

                        UInt16 nameLength = BitConverter.ToUInt16(nameLengthBytes, 0);

                        if (debug)
                        {
                            Console.WriteLine("Length of file name is: {0}", nameLength);
                        }

                        //get the name out of the file
                        List <byte> byteNameRaw  = new List <byte>();
                        List <byte> byteName     = new List <byte>();
                        int         prefixLength = (inFile.ReadByte() ^ key.getKeyByte());
                        int         suffixLength = (inFile.ReadByte() ^ key.getKeyByte());
                        fileIndex += 2;

                        if (debug)
                        {
                            Console.WriteLine("Prefix and Suffix lengths: {0}, {1}", prefixLength, suffixLength);
                        }

                        for (int i = 0; i < nameLength + prefixLength + suffixLength; i++)
                        {
                            byteNameRaw.Add((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                        }
                        fileIndex += nameLength + prefixLength + suffixLength;

                        //take only the filename out
                        for (int i = 0; i < nameLength; i++)
                        {
                            byteName.Add(byteNameRaw[i + prefixLength]);
                        }
                        outName = Encoding.Unicode.GetString(byteName.ToArray());

                        Console.WriteLine("Extracting {0}", outName);

                        byte[] fileSizeBytes = new byte[4];
                        for (int i = 0; i < 4; i++)
                        {
                            fileSizeBytes[i] = (byte)(inFile.ReadByte() ^ key.getKeyByte());
                        }
                        fileIndex += 4;
                        UInt32 inFileSize = BitConverter.ToUInt32(fileSizeBytes, 0);

                        //Attempt to create directory, just to be sure
                        Directory.CreateDirectory(Path.GetDirectoryName(root + "\\" + outName));
                        //now get the rest of the file
                        if (debug)
                        {
                            Console.WriteLine(("Writing to: " + Path.GetDirectoryName(path) + "\\" + outName + "\n"));
                        }
                        using (FileStream outFile = File.Open((Path.GetDirectoryName(path) + "\\" + outName), FileMode.Append))
                        {
                            //FileInfo inFileSize = new FileInfo(path);
                            for (int i = 0; i < inFileSize; i++)                            //fileToDecrypt.Length; i++)
                            {
                                outFile.WriteByte((byte)(inFile.ReadByte() ^ key.getKeyByte()));
                            }
                        }
                        fileIndex += (int)inFileSize;
                        if (debug)
                        {
                            Console.WriteLine("File index is {0}", fileIndex);
                            Console.WriteLine("Length of extracted Data is {0}", 4 + byteNameRaw.Count + 4 + inFileSize);
                        }
                    }
                }
                File.Delete(path);

                if (debug)
                {
                    sw.Stop();
                    Console.WriteLine("Elapsed time: {0}\n", sw.Elapsed);
                    sw.Reset();
                }
                key.resetKey();
            }
        }