Lukas
Lukas

Reputation: 3

Secure XOR encryption attempt

This is my first post and I am very sorry if I made errors with the format.

I am trying to write a program to encrypt all kinds of file via XOR in a secure way. I know that XOR isn't the most secure encryption method but I wanted to give it a try. So please have a look on my methode and tell me if it is complete bullshit or not :) The password is a String, chosen by the user. In the beginning I only XORed the file with the password, leading to an easy decryption if parts of the password were guessed correctly.

Here is my procedure:

  1. TmpFile = File XOR (hash of password combined with the pw.length.toString) //to make sure that the password elements are in the right order
  2. TmpFile = TmpFile XOR (XOR byte composed by each byte of the password)//ensure that the password to decode has exactly the right chars.
  3. TmpFile= TmpFile XOR initial_password

Could the encrypted text be decrypted with the self-XOR-shifting technique?

Thanks for your advice! :)

edit: here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security;
using System.IO;
using System.Windows;

namespace EncodeEverything
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("FileEncrypter v01 \n \n");


                //get password
                Console.WriteLine("Enter your Password (encryption key)");
                string password = getPassword();
                Console.WriteLine("");

            while (true)
            {

                Console.WriteLine("");
                Console.WriteLine("-----------------------");
                Console.WriteLine("");

                //get file to encrypt
                Console.WriteLine("File to encrypt/decrypt:");

                Console.Write("  ");
                string path = Console.ReadLine();

                //-------------------------------
                //load, encrypt & save file
                //-------------------------------
                try {
                    Byte[] tmpBArr = encrypt(File.ReadAllBytes(path), getCustomHash(password));
                    File.WriteAllBytes(path, encrypt(tmpBArr, password));
                    Console.WriteLine("    done.");
                }
                catch(System.Exception e)
                {
                    Console.WriteLine("!! Error while processing. Path correct? !!");
                }

            }
        }

       private static string getCustomHash(string word)
        {
            string output = "";

            output += word.Length.ToString();
            output += word.GetHashCode();

            return output;
        }

        //encrypt bzw decrypt Byte[]
        public static Byte[] encrypt(byte[] s, string key)
        {
            List<Byte> output = new List<byte>();
            Byte[] codeword = Encoding.UTF8.GetBytes(key);

            Byte keybyte =(Byte)( codeword[0]^ codeword[0]);
            foreach(Byte b in codeword)
            {
                keybyte = (Byte)(b ^ keybyte);
            }

            for (int i = 0; i < s.Length; i++)
            {
                output.Add((Byte)(s[i] ^ codeword[i % codeword.Length] ^ keybyte));
            }

            return output.ToArray();
        }



        public static string getPassword()
        {
            Console.Write("  ");

            string pwd = "";
            while (true)
            {
                ConsoleKeyInfo i = Console.ReadKey(true);
                if (i.Key == ConsoleKey.Enter)
                {
                    break;
                }
                else if (i.Key == ConsoleKey.Backspace)
                {
                    if (pwd.Length > 0)
                    {
                        pwd= pwd.Remove(pwd.Length - 1);
                        Console.Write("\b \b");
                    }
                }
                else
                {
                    pwd+=(i.KeyChar);
                    Console.Write("*");
                }
            }
            return pwd;
        }

    }
}

Upvotes: 0

Views: 2294

Answers (2)

CodesInChaos
CodesInChaos

Reputation: 108810

  1. string.GetHashCode doesn't have a well defined return value. So you might not even be able to decrypt the file after you restart the process.
  2. Your key consists of a 32 bit value plus the length of the password. Brute-forced in seconds on a single computer.
  3. Once the file is longer than the hashed key, the key starts repeating, you get a many-time-pad. So even if we ignored the brute-force attack, it'd still be easy to break. It's essentially a xor based vigenere variant.
  4. Ignoring the xor-ed parity byte, which is the same for each byte in the message, the key-stream bytes are ASCII digits, so each key byte has at best 3.3 bits of entropy. Comparing this with the approximately 1.5 bits of entropy per letter in English text, shows you that it's quite weak, even without key-stream repetitions.

=> it's buggy and insecure

Upvotes: 3

Jakotheshadows
Jakotheshadows

Reputation: 1515

You can ignore this answer if you're just trying to encrypt files as a learning exercise in cryptography, but if you're looking for a real-world solution to securing your file data, read on.

I'd really recommend that you use File encryption built into the .NET framework for this sort of thing if you're looking for a real-world solution to keeping your file data secure.

From Microsoft @ https://msdn.microsoft.com/en-us/library/system.io.file.encrypt(v=vs.110).aspx

using System;
using System.IO;
using System.Security.AccessControl;

namespace FileSystemExample
{
    class FileExample
    {
        public static void Main()
        {
            try
            {
                string FileName = "test.xml";

                Console.WriteLine("Encrypt " + FileName);

                // Encrypt the file.
                AddEncryption(FileName);

                Console.WriteLine("Decrypt " + FileName);

                // Decrypt the file.
                RemoveEncryption(FileName);

                Console.WriteLine("Done");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }


        // Encrypt a file.
        public static void AddEncryption(string FileName)
        {

            File.Encrypt(FileName);

        }

        // Decrypt a file.
        public static void RemoveEncryption(string FileName)
        {
            File.Decrypt(FileName);
        }
    }
}

It is hard to say for sure that this is what you need, because other things may need to be taken into consideration such as whether you need to pass the file between different clients/servers etc, as well as how much data you're encrypting in each file.

Again, if you're looking for real-world cryptography using C#, I can't stress enough that you should be looking to built-in .NET encryption rather than trying to roll your own- especially if you don't have any formal training in the subject matter. I recommend you pore through Microsoft documentation on .NET framework encryption if you're interested in securing data in production:

https://msdn.microsoft.com/en-us/library/0ss79b2x(v=vs.110).aspx

Here is a nice walkthrough for creating an example file encrypting windows form application:

https://msdn.microsoft.com/en-us/library/bb397867(v=vs.110).aspx

Upvotes: 1

Related Questions