【问题标题】:Encryption/Decryption in .NET.NET 中的加密/解密
【发布时间】:2010-09-14 15:54:49
【问题描述】:

我正在寻找一种在 Visual Studio 项目(C# 中)中加密和解密字符串的安全方法。我发现有原生的 DES 类,但不够安全。你有什么建议吗?

更新: 好的,那么问题是:什么是最安全的加密/解密字符串的方法而没有太多麻烦(也就是必须安装外部工具等。虽然外部库很好)。以及将秘密“密钥”放在哪里(在代码中编译值是否足够安全?)。

更新 #2 如果我使用类似这样的代码将加密字符串保存在配置文件中:

using System.Security.Cryptography;
using System.Security;
byte[] encrypted = ProtectedData.Protect(StrToByteArray("my secret text"), null, DataProtectionScope.LocalMachine);
byte[] derypted = ProtectedData.Unprotect(encrypted , null, DataProtectionScope.LocalMachine);

这足够安全吗?我猜想使用“LocalMachine”参数而不是“User”参数,有人可以在.net 中编写一个应用程序,将它放在机器上并执行它来解密加密的字符串。所以如果我想让它更安全,我必须为每个用户设置一个不同的配置文件?我理解正确吗?

【问题讨论】:

  • 在这一点上,DES 还不够安全,无法阻止我的小妹妹。
  • 什么 dtb 说的。另外,当您找到 DES 类时,您没有注意到这里的 AES、RSA、Rijndael 类 msdn.microsoft.com/en-us/library/…?
  • DES、TripleDES、AES、Rijndael 等对称加密算法的“安全性”主要取决于破解它们所需的时间。 AES 在这方面优于 DES。但弱点通常在其他地方,例如保护对称密钥、选择正确的填充或防止social engineering。攻击者倾向于攻击最薄弱的地方,而不是你最关注的地方。
  • @erickson:我的观点是:如果您按照解密方法发送对称密钥,我可以立即“破解”DES 和 AES。实际上,启动 Reflector 并找到密钥比解密秘密数据需要更多的时间。
  • @dtb - 对。但我的观点是,如果你正确实现了你的协议但选择了 DES,你就完蛋了,而如果你选择了 AES 之类的东西,你就安全了。

标签: c# .net encryption


【解决方案1】:

要回答您的第二个问题,不,将加密密钥存储在可执行文件中,即使被混淆,也根本不安全。它会保持随意的窥探,但不会让那些有一个小时花时间浏览你的反编译源的人。

仔细考虑在哪里存储您的加密密钥 - 看起来这将是您的弱点。是的,这是一个很难解决的问题。存储加密密钥的最安全方式是不要求用户输入密码,或要求外部硬件,如密钥卡。

如果您要加密仅在单台计算机上或由单个域用户读取的内容,请考虑使用Data Protection API (DPAPI)。它将加密密钥从您手中夺走 - 它使用用户的 Windows 凭据作为密钥。

我在这里的另一个答案中有更多细节:Persistent storage of encrypted data using .Net

关于您的第二次编辑(DataProtectionScope.LocalMachine 是否足够好?); this MSDN blog entry总结的很好:

设置范围 DataProtectionScope.CurrentUser 加密数据,以便只有 当前登录的用户可以解密 它。切换到 DataProtectionScope.LocalMachine 允许任何进程在 当前机器解密数据。 这在服务器中可能很有用 场景,其中没有不受信任的 登录到机器,但对于 通用工作站使用 LocalMachine 加密差不多 相当于在 全部(因为任何登录的人都可以获得 数据)。

【讨论】:

  • 我明白了。所以基本上,如果我想在配置文件中存储一个安全字符串,我必须为每个登录的用户创建一个不同的文件,或者使用来自远程服务的密钥?
  • 确实,第二段很关键。请记住:密码系统的目的是将短密钥的安全性利用到长秘密消息的安全性。强加密的全部要点是您的长密钥秘密消息的安全性完全地与您愿意为保持密钥秘密所付出的努力一样安全。 您如何选择对密钥保密并不是密码系统的一部分:这是您必须自己解决的问题。 密码所做的只是减少您的数据量必须保持隐藏。它并没有消除隐藏 something! 的要求
【解决方案2】:

它还有AES

【讨论】:

    【解决方案3】:

    如果我正确阅读了您的更新,您基本上是想隐藏一些字符串常量,以免系统管理员窥探您的程序集。

    没有办法让有太多时间的人最终提取你的字符串常量。但是你可以惹恼他们,希望他们在揭露你的秘密之前放弃尝试。

    实现这一目标的一种方法是混淆工具。这些会尽可能地混淆您编译的程序集,从而在使用 Reflector 反编译程序时更加难以遵循程序流程。尝试一下。如果您的字符串常量仍然不够隐藏,您可以另外发明自己的方案以使其更难找到。

    如果您需要更高的安全性,几乎唯一的选择就是不将代码的相关部分提供给用户。创建一个包含应用程序机密部分的 Web 服务,并使用 SSL/TLS 保护连接。

    【讨论】:

    • 我对此表示反对,因为混淆是比 DPAPI 更糟糕的答案。
    • @Steven Sudit:但是如何将数据放入 DPAPI 存储?如果您没有亲自到场输入密码,那么您必须再次将其隐藏在代码中的某个位置。也许这对 OP 来说不是问题,但仍然没有真正了解他的情况。
    • 您将其作为安装的一部分进行。关键是你的代码中永远不会有秘密。
    • @Steven Sudit:所以你在安装程序可执行文件中嵌入了秘密?
    • @Steven Sudit:这真的取决于。选择安全策略始终是分析资产的珍贵程度以及需要多少保护的结果。因此,如果混淆对他的用例来说足够好,那么混淆就足够好了。你不能否认重言式的真实性。 :-)
    【解决方案4】:

    尝试使用AesManaged

    【讨论】:

    • 这真的不比使用msdn.microsoft.com/en-us/library/…差多少,所以我不明白反对意见。
    • 我认为 MSDN 或 SO 链接都可以。这个答案对我来说看起来不错。
    【解决方案5】:

    这取决于您对足够安全的定义。您可以使用三重 DES。 .Net 也有原生的 Rijandel 类。是否足够安全? http://www.obviex.com/samples/Encryption.aspx

    【讨论】:

    • 澄清一下,Rijandel AES。
    • @Steven Sudit:不。AES 是 Rijndael,但 Rijndael 不是 AES。 (AES 是操作模式的一个子集。)
    • 真的有人在 AES 之外使用 Rijndael 吗?
    • @dtb:这不是一个反问。
    • @Steven Sudit:如果您的评论是“澄清一下,AES Rijndael”,我什么也不会说。 :-)
    【解决方案6】:

    使用经过良好测试和接受的库也是一个好主意...

    http://www.bouncycastle.org/csharp/

    【讨论】:

    • 这是一个讽刺的反对票吗? “是的,就像我会使用最好的加密库一样愚蠢,我会推出自己的”
    • 我不同意反对意见,但也许我的想法是 .NET 附带的内置加密类就足够了。
    • IMO 一个经过良好测试和接受的库是一个先决条件,但不能保证生成的应用程序是安全的。正确使用加密算法真的很难做到。
    • @dtb:你没看错。最好避免尝试提出新颖的解决方案。如果可能,请完全避免使用 crpyto 原语并坚持使用更高级别的构造。
    • @Steven Sudit:不幸的是,.NET Framework 和 Bouncy Castle 都缺少这些高级构造。看看所有在数据库中存储加盐哈希的可怕的本土解决方案。
    猜你喜欢
    • 1970-01-01
    • 2010-12-13
    • 2011-01-10
    • 2011-01-10
    • 2011-08-19
    • 2014-06-02
    • 2019-02-12
    • 1970-01-01
    相关资源
    最近更新 更多