2011-04-12 45 views
0

我一直在做一些关于创建.NET应用程序中使用的加密/解密类的研究。一次又一次,我读到除秘密密码外还需要盐。今天我遇到了一种只使用一个密码的加密/解密方法。这段代码使用的加密方法是否有问题,因为它似乎没有使用盐?只有密码的加密示例...没有盐。它工作吗?

Public Shared Function EncryptString(ByRef input As String, ByRef password As String) As String 
    Dim RijndaelManagedObject As New RijndaelManaged 
    Dim crypto As ICryptoTransform, MD5Obj As New MD5CryptoServiceProvider 
    Dim EncryptedBytes As Byte() 
    Dim HashedBytes As Byte() = New ASCIIEncoding().GetBytes(password) 
    Dim PlainTextBytes As Byte() = New ASCIIEncoding().GetBytes(input) 

    RijndaelManagedObject.BlockSize = 128 
    RijndaelManagedObject.KeySize = 128 
    RijndaelManagedObject.Mode = CipherMode.ECB 
    RijndaelManagedObject.Padding = PaddingMode.Zeros 
    RijndaelManagedObject.Key = MD5Obj.ComputeHash(HashedBytes) 
    crypto = RijndaelManagedObject.CreateEncryptor() 
    EncryptedBytes = crypto.TransformFinalBlock(PlainTextBytes, 0, PlainTextBytes.Length) 

    If EncryptedBytes.Length > 0 Then 
    Return Convert.ToBase64String(EncryptedBytes) 
    Else 
    Return String.Empty() 
    End If 
End Function 

回答

2

不,这没什么错。

Salting密码是为了防止彩虹表攻击,当你存储那些散列密码。在这种情况下,密码正被用于生成加密/解密密钥并且未被存储。

3

此代码具有许多缺陷:

  1. 如果inputpassword非ASCII无声发生降解。特别是非ascii input将不会被正确解密。
  2. 您不需要使用很多次迭代,这意味着如果真的很快就会蛮横的。
  3. 由于散列不是直接知道的,因此缺少盐的情况比使用密码散列难以在此处显示。但是,如果你用一个已知的起始块(这在许多文件头中很常见)对文件进行加密,那么可以为这种格式创建一个彩虹表。但是,如果你只是试图破解一个文件/散列,就像往常一样,彩虹表不会为你带来任何好处。如果您需要破解以相同方式使用的许多不同密码,它们只会获益。
  4. 不建议使用ECB模式,因为它会分别加密每个块。这使得3)的问题变得更糟,因为你只需要知道任何块的明文就可以建立一个表。特别是最后的块通常具有低熵。我希望每个第16组数据中只有8位熵。哎哟。
  5. 我不确定PaddingMode.Zeros是如何工作的。但是由于它的长度没有被编码,所以可能无法去除填充。所以解密后你可能会有一些额外的0字节。

电子密码本(ECB)模式分别加密每个块。任何相同且在相同消息中的纯文本块或者在使用相同密钥加密的不同消息中的明文块将被转换为相同的密文块。重要提示:建议不要使用此模式,因为它为多种安全漏洞打开了大门。如果要加密的纯文本包含大量重复,则密文一次可以分解一个块是可行的。也可以使用块分析来确定加密密钥。此外,活跃的对手可以替代和交换各个块而不进行检测,这允许将块保存并在没有检测到的情况下插入到其他点的流中。