views:

237

answers:

5

I am looking to encrypt data. I want to generate encryption keys based on a password, and some moving value, like time. The goal is to have the key change, but have anyone that knows the password be able to decrypt. This is happening in C#. I am using the following code to hash the password.

private static string GetPasswordHash(string password)
{
    TimeSpan span = (DateTime.UtcNow - new DateTime(1900, 1, 1));
    string result = Convert.ToInt32(span.TotalHours).ToString();
    result += password;
    result += Convert.ToInt32(span.TotalDays).ToString();
    result = Convert.ToBase64String(SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(result)));
    return result;
}

I then use that hash, plus a salt to generate a key.

        Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(GetPasswordHash(password), salt);
        rdb.IterationCount = 1000;

        RijndaelManaged rm = new RijndaelManaged();
        rm.KeySize = 256;
        rm.Key = rdb.GetBytes(32);
        rm.IV = rdb.GetBytes(16);

There seem to be issues with the way I am doing this. Some of the computers are in different timezones, or if the hour ticks as I send the data, or if the machines times are slightly off. Are there better suggestions?

+1  A: 

You could find a scheme that generates the same moving value over a window of time, centered on the current time. Thus, if you choose a window of 12 hours, all computers 6 hours behind and 6 hours ahead of yours would generate the same encryption key.

JoshJordan
+2  A: 

You might just send the changing part (unencrypted) along with the encrypted data, so that anyone who knows the secret password can easily reconstruct the password used for encryption. Since the changing part is relatively easy to guess, it wouldn't make it much less secure.

ammoQ
+8  A: 

The standard strategy is to just send the value (time, etc.) just be sent with the encryption key. Since the value you are using is public knowledge, it is fine if whoever first creates the password provides the "moving value" publicly. See Salt. What you are doing is not a new technique. You also seem to be using Key Strengthening.

Brian
A: 

Are you worried that a file with the same data encrypted with the same password looks the same? You could use set the initialisation vector with the current time, and encrypt using your password. To decrypt, you use the same IV value (so this has to be stored unencrypted with your file somewhere).

DanDan
A: 

Password based key derivation is already implemented in .net. While I can't see anything wrong with your function GetPasswordHash() its always worth using library functions in crypto as they'll likely be better tested and small errors can completely destroy the security of a system. Here're two links, there are probably others too:

rfc2898derivebytes

passwordderivebytes

Patrick