Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Rijndael加密算法中创建自定义长度密码_C#_Rijndael - Fatal编程技术网

C# 在Rijndael加密算法中创建自定义长度密码

C# 在Rijndael加密算法中创建自定义长度密码,c#,rijndael,C#,Rijndael,我使用c#实现Rijndael算法来加密/解密文件。下面是我的代码: private void EncryptFile(string inputFile, string outputFile, string password) { try { UnicodeEncoding UE = new UnicodeEncoding(); byte[] key = UE.Ge

我使用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等,那么它就可以工作,否则就不行。

伪代码=>

 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
    }
 }
字符串密码FlagLength(字符串密码)
{
整数计数=1
对于(int i=0到31)
{
如果(password.length==count)返回密码;
如果(password.length
这需要一个密码,并使其长度为1、2、4、8等。。。高达31位的值。(整数带负输出)

如果该值已经是一个合适的标志大小数字,它将使用它,否则它将用“x”填充其余部分


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

简单地获取密码并以字节为单位获取其Unicode表示形式会使密钥变得非常糟糕。请不要那样做!正确的方法是使用salt散列作为密钥——也就是说,使用salt和密码,并将它们与散列函数混合在一起

要从可变长度密码派生密钥,请使用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基类分支出来,并使用更现代的算法,如。

将密钥用于IV会破坏CBC的目的,并大大降低安全性。安全性很难实现。在安全使用加密原语之前,您需要了解更多关于加密的知识。您忘记问一个问题:)@SLaks,我同意您的两个意见,但是,这是一个学习的好地方。@Jodrell:不;这太宽泛了,不能这样教。试图使答案更具体地反映他的询问。