Rijndael算法加密功能 - 钥匙/ IV /盐安装(Rijndael Cryptography

2019-10-21 13:04发布

我工作的一个简单的工具,以文件作为一个学习的经验进行加密。 似乎一切都工作正常,但我想知道如果我有安装密钥/ IV /盐的数据安全。

我注意到,当涉及到密码学大多数人似乎设想,加载恶意软件通过远程准备通过正在运行的应用/页面文件的内存潜水让这些安全文件向导载人的工作环境。

让我们假设你是一个干净的机器上,你加密了一些文件,并关闭计算机。 我想知道的是,是否有人可以把你的硬盘驱动器,并使用我提出的代码检索文件的内容。

攻击向量我最关心的是确保页面文件/文件缓存是无法访问。 我也想,以确保使用的密钥/ IV系统不会让一个彩虹表/基于哈希的攻击是可行的。

输入密码:

使用设置为true的passwordchar值的文本框中输入的密码。

我真的不关心串在内存中,只要它是加密后正常删除之中。 我读了使用SecureString的是一种毫无意义的在这一点上,因为如果您的计算机上有恶意软件已经,你可以很容易地对其中有一个键盘记录使一切无用的。

private static string salt = "02341235XadfaDADFexA8932F7Dz3J3X";

I盐使用硬编码的32字符串的密码。 (以上字符串是只是一个例子。)

为了得到它,它需要有人反编译/浏览.exe文件本身有一个十六进制编辑器(的东西,我知道,如果很容易做到,但仍然一个额外的步骤)。

我曾考虑让这种盐可编辑的,但我不知道我怎么能安全地保存它。 我认为这是一个有点可笑加密您的盐,因为那么你将有同样的问题等,所以只是把它当作自己似乎最有意义给我的exe文件内的硬编码字符串。

其工作原理是,如果你决定把你的密码“thepassword”,它实际上是保存为“thepasswordfaDADFexA8932F7Dz3J3X”。

这里主要的关键是,你总是有一个32字符的密码,无论你输入什么的。

密钥和IV:

密钥和IV也腌如下。 这是我想获得一些意见,因为说实话,我不是很确定那是什么做的:

UnicodeEncoding UE = new UnicodeEncoding();
byte[] keysalt = UE.GetBytes("Xjafe231x42X423XadXCadfkhjeAdS");        //Another string of random characters hard coded in the exe
byte[] IVSodium = UE.GetBytes("83Xkda7l78Dkx85KdJazppoqq6SaxDs");        //Another string of random characters hard coded in the exe
byte[] key = new Rfc2898DeriveBytes(password, keysalt).GetBytes(32);   //Derive the key using the password and salt
byte[] IV = new Rfc2898DeriveBytes(password, IVSodium).GetBytes(16);    //Derive the IV using the password and salt

我这里主要关注的是,四是基于关键。 同样,我不知道这是否会造成任何问题,我希望你们可以让我知道,如果有问题,它们是什么。

此外,这是另一种情形,其中硬编码的盐是一种不好的做法? 如果这被保存在加密文件,如果是的话,它真的使之更加安全? 我应该让这个编辑呢?

该加密流是使用使用关键字的设置:

using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
    using (RijndaelManaged RMCrypto = new RijndaelManaged())
    {
        using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
        {
            using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
            {
                byte[] buffer = new byte[4096]; //4096 is kind of arbitrary - better idea?
                int data;
                long bytesRead = 0;
                while((data = fsIn.Read(buffer, 0, buffer.Length)) > 0)
                {
                    bytesRead += data;
                    /////////////////////////////////////////
                    // Handle Aborts and Update Progress Bar
                    /////////////////////////////////////////
                    if (!caller.isClosing)
                        caller.Invoke((MethodInvoker)delegate {
                            caller.fileProgressBar.Value = ((int)(((double)bytesRead / totalBytes) * 100)); 
                        });
                    else
                        return false; //Encryption Aborted
                    /////////////////////////////////////////
                    cs.Write(buffer, 0, data);
                    fsIn.Close();
                    cs.Close();
                    fsCrypt.Close();
                    return true;
                }
            }
        }
    }
}

感谢您的时间和请让我知道,如果有设置键/ IV /盐更好的办法。 我认为它是最有可能的足够安全,只要没有与IV和密钥包含相似字符的数学问题。 如果是这样,我应该使用硬编码IV呢? 这似乎不可思议。

请注意,我不保存密码或类似的东西的哈希值。 该密码不保存任何地方。 它只是用来生成密钥和IV。

谢谢你的时间。

编辑:这里是建议任何人都希望在未来的变化。

请注意,这不是用胡椒-只是一个随机的盐,虽然这将是足够的添加容易

byte[] salt = new byte[32];                                        //Create a 32 byte salt
rand.NextBytes(salt);                                              //Fill it with random values (use RandomNumberGenerator rand = new RNGCryptoServiceProvider(); to be safe
byte[] IV = new byte[16];                                          //Create a 16 byte IV
rand.NextBytes(IV);                                                //Fill it with random numbers
byte[] key = new Rfc2898DeriveBytes(password, salt).GetBytes(32);  //Derive our Key by mixing our password with the salt

using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
    using (RijndaelManaged RMCrypto = new RijndaelManaged())
    {
        using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
        {
            using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
            {
                fsCrypt.Write(salt, 0, salt.Length); //Write our salt to the file
                fsCrypt.Write(IV, 0, IV.Length);     //Write our IV to the file
                fsIn.CopyTo(cs);                     //Encrypt and Write
            }
        }
    }
}

Answer 1:

该盐被用于两个目的:

  1. 防止彩虹表攻击(和是否正确应用);
  2. 防止相同的密码来生成相同的密码散列。

要做到这一点的盐需要是随机数据的8至16 个字节 (而不是字符),存储有密码哈希。 使用静态哈希你做失败的哈希的这两个目的。

如果你需要的字符串,使用基64编码盐和密码哈希。 如果你愿意,你可以添加静态数据(有时称为“辣椒”),以盐调用密码哈希函数之前。 这可能会增加一些安全性,如果该程序的数据不能被容易被攻击者读取。

你不应该直接混合盐和密码自己; 在Rfc2898DeriveBytes(这是PBKDF2的实现)已经将两者。 你也永远不应该存储密码,你也不应该有任何数据追加到它。 PBKDF2可以处理输入的任何尺寸,所以它不添加任何功能。

现在IV可以从PBKDF2函数(使用采取GetBytes )。 但是这里有一个问题,很可能,这将增加一倍PBKDF2功能,花费CPU时间,减少了攻击者的优势迭代的初始确认金额。 它可能会更好,只是生成一个随机IV和它的前缀,在密文。

那么到底应该存储salt | IV | ciphertext salt | IV | ciphertext salt | IV | ciphertext ,然后用salt | pepper salt | pepper盐和计算你键,然后加密/使用计算出的密钥来解密和IV。



Answer 2:

我所知道的,

  1. IV /盐并不需要是私有的。 它可以存储在硬盘上的纯文本。 事实上,盐必须是纯文本,否则无法产生与它相同的输出。
  2. 它不是用你的密钥信息生成IV,因为它可能会泄露你的关键信息是个好主意。
  3. 有没有办法可以防止如虹的攻击。 但随着盐,彩虹攻击变得昂贵的talbes只有这种盐值工作。
  4. 有密钥推导温控功能的标准,可能对你有用( http://en.wikipedia.org/wiki/PBKDF2 )。


文章来源: Rijndael Cryptography Function - Key/IV/Salt Setup