【问题标题】:Encrypting and decrypting a string using Rijndael使用 Rijndael 加密和解密字符串
【发布时间】:2013-02-27 16:19:20
【问题描述】:

在开始之前,我知道在 stackoverflow 上有很多类似的问题,但大多数答案都包含一大段代码,没有任何解释或帮助帮助用户。

我需要做的很简单,从用户那里获取一个字符串作为输入,然后是密码,然后用密码加密字符串并将密文写入文件。然后在用户需要时,从文件中读取密文并对其进行解密,并向用户呈现原始纯文本。我可以处理文件的写入和写入,我只需要加密字符串的帮助。 (注意:我不想只加密/解密整个文件 - 因为它必须包含一些未加密的东西 - 只是程序中的一个字符串)

此外,所需的“初始化向量” - 可以与密码相同吗?或者它可以简单地硬编码到程序中吗?它甚至对安全至关重要吗?如果没有,那么用户是否必须记住密码和 IV?

另外一件事,当用户来解密并输入错误的密码时,Rijndael 类中的方法是否只是引发错误或什么?

我精通 C#,但我是密码学新手,所以如果您能指导我完成任何代码或回答您的帖子,我将不胜感激。

谢谢

【问题讨论】:

  • 哈维你有没有做过其他的互联网搜索..?这是一篇很好的文章来解释如何Encrypt & Decrypt using Rijndeal
  • 您好,请查看 MSDN 上涵盖此主题的这篇文章 - 有很多代码,但它的注释(几乎逐行)解释了每个阶段发生的事情 - 它可能无法完全回答您的问题问题但它应该为您提供对流程的深入了解! msdn.microsoft.com/en-us/library/…

标签: c# security cryptography aes rijndael


【解决方案1】:

大多数 Rijndael 模式都需要 IV,通常您只需将其添加到密文中,无需用户记住。

由于您使用用户输入的密码进行解密,因此您希望使用Authenticated Encryption,以便您的程序可以在输入错误密码时安全地重新提示,否则您的程序可能不会给出任何指示存在问题并且吐出随机文本。

我有一个使用带有 HMAC-SHA256 身份验证的 AES-CBC 的示例,我尝试更新并进行了审查,它实际上有一个帮助方法,只使用明文和密码处理加密,并且评论也很好:

Modern Examples of Symmetric Authenticated Encryption of a string. C#

【讨论】:

  • 如果密文很长,您可能还需要存储一些额外的数据(例如空消息的 MAC),以便在无需先处理整个密文的情况下检测输入错误的密码。跨度>
  • @IlmariKaronen 这真的不是实现检测错误密码目标的方法。唯一的方法是通过 MAC 或 CCM 或 GCM 等经过身份验证的加密模式。
  • @PeterElliott:你介意解释一下为什么你这么认为吗?对密文进行 MAC 化(或使用 AE 模式)的主要目的是保护其免受恶意篡改;事实上,使用不正确的密钥也会导致 MAC 失败,这实际上只是一个副作用,并不是检查密码正确性的好方法。 (一方面,您无法通过这种方式区分错误密码和损坏的密文。另一方面,您需要处理整个密文以检测 MAC 故障。)
  • (续)更好的解决方案是在尝试处理任何实际密文之前验证密钥(但在使用合适的密钥扩展 KDF 从密码中导出密钥之后)像 PBKDF2 或 scrypt;除了输入到 KDF 之外,您永远不应该将原始密码用作其他任何东西)。一种方法是存储密钥的加盐哈希,或带有密钥的短随机消息的 MAC。 (我之前关于使用空消息的建议有点次优如果 KDF本身没有加盐,当然应该是这样;有关更多详细信息,请参见例如crypto.stackexchange.com/q/1507。 )
  • @IlmariKaronen 公平地说,它并不是 encrypt-then-mac 或 AEAD 的真正副作用,它们都提供确定性的方法来验证您是否拥有有效的密文,无论密文是否无效,因为来自在这两种安全结构中,攻击者、篡改或由于您自己的错误而与​​您的密钥不匹配均无关紧要。
【解决方案2】:

您需要采取以下步骤:

  1. 根据密码计算密钥。您需要生成一个 8 字节的随机盐和一个迭代计数作为基于密码的密钥派生函数 (PBKDF)(例如 PBKDF2)的输入;
  2. 使用任何编码(例如 UTF-8)对字符串进行编码,为您提供密码的明文;
  3. 使用 PKCS#7 填充创建密码,例如 CBC 模式下的 AES-128;
  4. 创建一个随机 IV,这应该是以字节为单位的块大小(因此对于 AES,这将是 16 个字节);
  5. 使用给定密码加密您的明文,为您提供密文;
  6. 存储 salt、IV 和密文 - 如果需要字符串,可以使用 Base64 等编码。

PBKDF2 在Rfc2898DeriveBytes 中实现。

请注意,此答案仅说明如何实现机密性,而不是完整性或真实性。

【讨论】:

  • 请注意,从技术上讲,both PBKDF2 的随机盐和随机 IV 并不是绝对必要的(但也不会造成伤害)。不过,+1。
  • @IlmariKaronen 是的,我知道,但是生成足够的随机数据来提取 IV 可能需要再次执行整个 PBKDF 函数,这也有其缺点。如果您有空间存储它,最好生成一个单独的 IV。感谢您的 +1。
  • 实际上,我上面的评论是错误的:我想说的是,如果您在 PBKDF2 中使用随机盐来派生密钥,并且仅使用该派生密钥来加密一条消息,那么使用固定的 IV 应该没问题。但是对于 CBC 模式实际上并非如此,尽管对于大多数其他模式来说确实如此。 (但是,即使对于 CBC 模式,您也可以通过使用原始分组密码加密随机数来导出 IV,如 NIST SP 800-38A,附录 C 中所示。随机数只需要在每个键的范围;如果键从不重复使用,则它可能是固定的。)
  • @IlmariKaronen 我认为如果您从不重复使用密钥进行加密,那么即使是零 IV 也是可以的,即使对于 CBC 模式也是如此。 NIST 文件谈到 IV 是不可预测的,但我假设(不正确?)标准期望密钥被多次使用(它没有说)。请注意,即使您只是为 TDEA 或 AES 创建密钥检查值 (KCV),此前提也会被打破。
  • 哈维,我的回答有什么问题吗?如果有,请通过评论告诉我,否则点击接受(阅读措辞优美的常见问题解答!)
猜你喜欢
  • 2012-12-14
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2012-07-01
相关资源
最近更新 更多