初学者:这是一个很好的加密吗?

时间:2014-03-07 12:58:32

标签: encryption .net pbkdf2

我设法将一些代码拼凑起来加密/解密字符串,我想知道我是否做得很好。换句话说,它是否真的安全。

我在StackOverflow帖子中读到重用IV是不好的做法,应该避免。我不能肯定地说,但我相信这就是我在这里所做的。确认/拒绝?

那就是说,不会为每个操作使用不同的IV来使加密流不可加密?恐怕我不太了解这个,就像我想的那样。

以下是代码:

Private Function Crypt(InBytes As Byte(), Password As String, Action As EncryptionActions) As Byte()
  Dim oCryptoTransform As ICryptoTransform
  Dim oDesProvider As AesCryptoServiceProvider

  Dim _
    iBlockSize,
    iKeySize,
    iSize As Integer

  Dim _
    aSalt,
    aKey,
    aIV As Byte()

  oDesProvider = New AesCryptoServiceProvider
  oDesProvider.Mode = CipherMode.CBC

  aSalt = {&H10, &H20, &H12, &H23, &H37, &HA4, &HC5, &HA6, &HF1, &HF0, &HEE, &H21, &H22, &H45}

  For iSize = 1024 To 1 Step -1
    If oDesProvider.ValidKeySize(iSize) Then
      iKeySize = iSize
      Exit For
    End If
  Next

  iBlockSize = oDesProvider.BlockSize

  With New Rfc2898DeriveBytes(Password, aSalt, 12345)
    aKey = .GetBytes(iKeySize \ 8)
    aIV = .GetBytes(iBlockSize \ 8)
  End With

  Select Case Action
    Case EncryptionActions.Encrypt : oCryptoTransform = oDesProvider.CreateEncryptor(aKey, aIV)
    Case EncryptionActions.Decrypt : oCryptoTransform = oDesProvider.CreateDecryptor(aKey, aIV)
    Case Else : Throw New ArgumentException("Invalid encryption action specified.")
  End Select

  Using oOutStream As New MemoryStream
    Using oCryptoStream As New CryptoStream(oOutStream, oCryptoTransform, CryptoStreamMode.Write)
      oCryptoStream.Write(InBytes, 0, InBytes.Length)
    End Using

    Return oOutStream.ToArray
  End Using
End Function

2 个答案:

答案 0 :(得分:2)

我不知道.net因此我不详细了解代码,但据我所知,至少存在以下问题:

  • 您没有使用经过身份验证的加密。您应该使用像HMAC这样的MAC来检测密文的操作。否则,攻击者可能会操纵密文,以便将其解密为合理的明文。
  • 对于DES,存在弱密钥。如果你运气不好,你的派生钥匙很弱,但获得弱钥匙的概率通常可以忽略不计。此外,您应该使用AES而不是3DES。
  • 我看不到您使用的密码模式。不建议使用欧洲央行。今天,大多数密码学家都推荐使用CBC或CTR。

您应该进行加密的方式如下:

  • 随机选择密钥或从密码中获取密钥
  • 在CBC模式下使用AES-256和PKCS#5填充
  • 随机选择一个IV
  • 加密数据
  • 在IV +密文上计算HMAC
  • 发送IV +密文+ HMAC

收到密文时:

  • 检查IV +密文的HMAC是否正确
  • 解密密文

答案 1 :(得分:2)

你的问题缺乏背景。你到底想要达到什么目的?更确切地说,你想要防御什么攻击?

据我了解,您的代码始终使用相同的密钥和初始化向量。

传递给PBKDF2的salt参数和传递给块密码的IV都应该使用适当的种子CSPRNG生成。在.Net中使用RNGCryptoServiceProvider

编辑:

盐和Ⅳ不是秘密。它们应该是消息或文件的一部分,或者代码产生的任何内容。

还有一条评论:您可能不应该使用硬编码的PBKDF2迭代次数。随着硬件变得更快,所需的迭代次数会随着时间的推移而增加。因此,迭代次数也应该是message / file / record / whatever的一部分。

相关问题