HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Simplifying Cryptography Key Generation without Losing Security

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withoutlosinggenerationsecuritysimplifyingcryptographykey

Problem

I am writing a helper class for encrypting string and other data types. My goal is to make it as easy as possible to use, while still keeping a substantial amount of security.

One issue I struggled with was simplifying all the different key and IV sizes. I've settled on having the caller provider a salt, and then generating my own key and IV data from the salt.

I assume this compromises the security very slightly, but not that much.

I would appreciate hearing other people's thoughts, especially those who have more experience with cryptography than I. Am I compromising my security too much?

public virtual byte[] EncryptBytes(byte[] data)
{
    using (SymmetricAlgorithm algorithm = TripleDES.Create())
    using (ICryptoTransform encryptor = algorithm.CreateEncryptor(GetKey(algorithm), GetIV(algorithm)))
    {
        MemoryStream ms = new MemoryStream();
        using (Stream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
        {
            cs.Write(data, 0, data.Length);
        }
        return ms.ToArray();
    }
}

public byte[] GetKey(SymmetricAlgorithm algorithm)
{
    return DeriveBytes(algorithm.KeySize / 8);
}

public byte[] GetIV(SymmetricAlgorithm algorithm)
{
    return DeriveBytes(algorithm.BlockSize / 8);
}

protected byte[] DeriveBytes(int bytes)
{
    Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(Password, Salt, 1000);
    return derivedBytes.GetBytes(bytes);
}

Solution

Why are you using 3DES instead of AES? Why is the algorithm hard-coded in EncryptBytes, but parameterized in GetKey() and GetIV()?

The last line looks suspicious — did you mean bits / 8?

protected byte[] DeriveBytes(int bits)
{
    Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(Password, Salt, 1000);
    return derivedBytes.GetBytes(bits / 8);
}


If so, then shouldn't it be…?

public byte[] GetKey(SymmetricAlgorithm algorithm)
{
    return DeriveBytes(algorithm.KeySize);
}

Code Snippets

protected byte[] DeriveBytes(int bits)
{
    Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(Password, Salt, 1000);
    return derivedBytes.GetBytes(bits / 8);
}
public byte[] GetKey(SymmetricAlgorithm algorithm)
{
    return DeriveBytes(algorithm.KeySize);
}

Context

StackExchange Code Review Q#96744, answer score: 7

Revisions (0)

No revisions yet.