在程序代码中安全地存储密码?

我的应用程序使用RijndaelManaged类来加密数据。 作为此加密的一部分,我使用加载了密码的SecureString对象,将其转换为字节数组并在运行时加载到RajindaelManaged对象的Key中。

我的问题是存储此SecureString。 用户输入的密码可以在运行时输入,并且可以“安全”加载到SecureString对象中,但如果没有给出用户输入的密码,那么我需要默认为某些东西。

所以问题最终归结为:

如果每次我的应用程序运行时都必须有一些已知的字符串或字节数组加载到SecureString对象中,我该怎么做? “加密”数据最终会被另一个应用程序解密,所以即使没有指定用户输入密码,我仍然需要在从一个应用程序转到另一个应用程序时对数据进行加密。 这意味着我不能将默认密码设为随机,因为其他应用程序无法正确解密它。

我正在考虑的一个可能的解决方案是创建一个仅发出单个密码的dll,然后我使用该密码并在运行时通过几个不同的散列/重组函数运行它,然后我最终将其提供给secureString对象。 这会足够安全吗?

编辑为清晰起见*:加密数据通过机器之间的文件传递。 将其视为始终具有密码的Zip文件,如果用户没有直接输入任何密码,则假定为默认密码。

使用硬编码到可执行文件中的字符串进行对称加密毫无意义。 它只会给人一种虚假的安全感。 没有任何哈希修复此方案。

请参阅此Pidgin常见问题解答 ,了解不同背景下的相同观点。

我不清楚为什么你认为你需要加密应用程序间通信。 如果此通信是本机的本地通信,那么我认为不需要加密,特别是非用户特定的加密。 这是DRM计划吗?

编辑:如果它被传递到另一台机器,也许你可以硬编码一个公钥 ,然后让另一台机器用匹配的私钥解密。

让我先解决你的最后一个问题。

“这会足够安全吗?”

唯一可以回答的就是你。 这里没有人知道在您的应用程序环境中“足够安全”的含义。

你正在建立一个应用程序来记录少女的日记吗? 当然,它会“足够安全”。

您是否正在构建一个应用程序来加密军用级安全系统的信息或身份validation? 没有,甚至没有关闭。

如果您打算将密码存储在源代码中并因此可执行,那么您只能依赖一种类型的安全性,这是默默无闻的安全性

如果您的问题是您不能或不会将密码存储在源代码中,那么将其移动到单独的dll中什么都不解决,您只是将问题移到了另一个项目中。

但是,我想知道一些事情。 你说“我必须默认一些东西”。 是吗? 您是否尝试在源代码中存储安全密码字符串的默认值? “THISISNOTAPASSWORD”怎么样?

Eric Lippert的你想喝盐吗? ( 原博客文章 )

另请阅读他的post, 使用正确的工具完成他的工作 ,并提供以下提示:

0)如果你可以的话,根本就不去那里。 加密是非常难以正确的,并且通常是首先是错误的解决方案。 使用其他技术来解决您的安全问题。

1)如果问题是不值得信任的客户端,则不要构建需要信任客户端的安全解决方案。

2)如果你可以使用现成的零件,那么这样做。

3)如果你不能使用现成的部件并且必须使用密码系统,那么不要使用你不完全理解的密码系统。

4)如果你必须使用一个你不完全理解的密码系统,那么至少不要用它来解决它不能解决的问题。

5)如果你必须使用密码系统在树上滑雪,那么至少不允许可能是恶意的客户端选择加密的消息。 自己选择令牌。 如果令牌必须包含来自客户端的信息,那么以某种方式对其进行清理; 要求它只是直接的ASCII文本,插入随机空格,等等。

6)如果您必须允许客户端选择令牌,则不要加密令牌本身。 签署令牌的加密安全散列。 攻击者更难以选择产生所需哈希的令牌。

7)不要像保护传入消息那样使用相同的密钥对来加密传出消息。 为您要执行的每个逻辑上不同的操作获取密钥对。

8)双向加密通信。

9)考虑使用撤销机制,这样一旦你知道Eve正在攻击你,你至少可以撤销她的执照。 (或者您可以撤销已知的已被入侵的许可证,依此类推。)

关于保护SQL连接字符串的这篇文章应该适用于存储加密密码,让操作系统为您的解密处理salting种子的加密。

听起来我可能应该使用PKI解决方案而不是加密/解密。 如果您有另一个需要使用加密数据的应用程序,那么您可以拥有该应用程序的密钥对,并将公钥提供给正在进行加密的应用程序。 这样你仍然可以保证数据安全,但不会引入一堆额外的代码,这些代码最终不能提供那么多保护。

快速谷歌搜索给了我这篇代码项目文章,讨论在.Net中使用Windows证书存储