0

I'm using c# for implementing Rijndael algorithm to encrypt/decrypt files. Below is my code:

private void EncryptFile(string inputFile, string outputFile, string password)
        {

            try
            {

                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password.ToString());

                string cryptFile = outputFile;
                FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

                RijndaelManaged RMCrypto = new RijndaelManaged();

                CryptoStream cs = new CryptoStream(fsCrypt,
                    RMCrypto.CreateEncryptor(key, key),
                    CryptoStreamMode.Write);

                FileStream fsIn = new FileStream(inputFile, FileMode.Open);

                int data;
                while ((data = fsIn.ReadByte()) != -1)
                    cs.WriteByte((byte)data);


                fsIn.Close();
                cs.Close();
                fsCrypt.Close();
            }
            catch
            {

            }
        }

Now, the thing is that, the function works only if password length is a multiple of 8. that is, if the password length is 8,16,32, etc., then it works else not.

Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93

2 Answers2

2

Simply taking the password and getting its Unicode representation in bytes makes pretty terrible key. Please don't do that! The correct way to go is to use a salted hash as a key -- that is, take a salt, a password, and mix them together with a hash function.

To derive a key from a variable-length password, use PBKDF2. PBKDF2 is designed to make brute forcing slower when the attacker has fast access to the data.

string password = ...;
byte[] salt = ...;
int keyLength = 32;

byte[] key;

using(var pbkdf = new Rfc2898DeriveBytes(password, salt))
{
    key = pbkdf.GetBytes(keyLength);
}

If you need something which uses less CPU, HMAC will work but also be faster to brute force:

using(var hmac = new HMACSHA256())
{
    hmac.Key = salt;
    key = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
}

Note that there exists hardware now which can very effectively attack PBKDF2 so this won't do much to help against a determined attacker with resources. If this is important to you, branching out of the .NET base classes and using a more modern algorithm like scrypt might be preferred.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
0

Pseudo Code =>

 string passwordFlagLength(string password)
 {
    int count = 1
    for (int i = 0 to 31)
    {

        if (password.length == count) return password;
        if (password.length < count) return password + new string("x", count - password.length);
        count = count * 2
    }
 }

This takes a password and makes it length 1, 2, 4, 8, etc... up to a 31 bit value.(int w/out negative)

if the value is already a proper flag size number, it uses it, otherwise it fills in the rest with "x"

--> Note: I agree with everyone elses comments regarding better was to do security/issues, I just posted this, because the immediate issue posted was due to a string size not being a base 2 bit value. I also just applied the count which I forgot in my original code