在Rijndael Cryptography算法中创建自定义长度密码

时间:2014-02-14 16:57:10

标签: c# rijndael

我正在使用c#来实现Rijndael算法来加密/解密文件。以下是我的代码:

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
            {

            }
        }

现在,问题是,只有当密码长度为8的倍数时,该功能才有效。即,如果密码长度为8,16,32等,则其他功能不起作用。

2 个答案:

答案 0 :(得分:2)

简单地获取密码并以字节为单位获取其Unicode表示形式是非常糟糕的关键。请不要那样做!正确的方法是使用盐渍哈希作为密钥 - 也就是说,取一个盐,一个密码,并将它们与哈希函数混合在一起。

要从可变长度密码派生密钥,请使用PBKDF2。当攻击者快速访问数据时,PBKDF2旨在使暴力破解变慢。

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

byte[] key;

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

如果您需要使用较少CPU的东西,HMAC可以工作,但也可以更快地使用强力:

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

请注意,现在存在可以非常有效地攻击PBKDF2的硬件,因此这对于确定具有资源的确定攻击者来说无济于事。如果这对您很重要,那么从.NET基类开始分支并使用更现代的算法(如scrypt)可能更受欢迎。

答案 1 :(得分:0)

伪代码=>

 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
    }
 }

这需要一个密码并使其长度为1,2,4,8等......最多为31位值。(int w / out negative)

如果该值已经是正确的标志大小编号,则使用它,否则用“x”填充其余部分

- &GT;注意:我同意所有人的观点,关于更好的是做安全性/问题,我刚刚发布了这个,因为发布的直接问题是由于字符串大小不是基本的2位值。我还在原始代码中应用了我忘记的计数