我的应用程序使用RijndaelManaged类来加密数据。作为此加密的一部分,我使用加载了密码的SecureString对象,该密码将被转换为字节数组并在运行时加载到RajindaelManaged对象的Key中。
我遇到的问题是存储此SecureString。用户输入的密码可以在运行时输入,并且可以“安全地”加载到SecureString对象中,但如果没有给出用户输入的密码,那么我需要默认为某些东西。
所以问题最终归结为:
如果每次我的应用程序运行时都必须将一些已知的字符串或字节数组加载到SecureString对象中,我该怎么做? “加密”数据最终会被另一个应用程序解密,因此即使没有指定用户输入密码,我仍然需要在从一个应用程序转到另一个应用程序时对数据进行加密。这意味着我不能将默认密码设为随机密码,因为其他应用程序无法正确解密它。
我正在考虑的一个可能的解决方案是创建一个仅发出单个密码的dll,然后我使用该密码并在运行时通过几个不同的散列/重组函数运行它,然后我最终将其输入secureString宾语。这会足够安全吗?
编辑为清晰起见*:加密数据通过机器之间的文件传递。将其视为一个始终具有密码的Zip文件,如果用户没有直接输入任何密码,则假定默认密码。
答案 0 :(得分:8)
使用硬编码到可执行文件中的字符串进行对称加密没有任何意义。它只会给人一种虚假的安全感。没有任何散列修复此方案。
请参阅this Pidgin FAQ了解不同背景下的相同观点。
我不清楚为什么您认为需要加密应用程序间通信。如果此通信是本机的本地通信,那么我认为不需要加密,特别是非用户特定的加密。这是DRM计划吗?
编辑:如果它被传递到另一台机器,也许您可以对public key进行硬编码,然后使用匹配的私钥解密另一台机器。
答案 1 :(得分:6)
让我先解决你的最后一个问题。
“这会足够安全吗?”
唯一可以回答的就是你。这里没有人知道在你的申请环境中“足够安全”意味着什么。
您是否正在构建一个应用程序来保存十几岁女孩的日记?当然,它会“足够安全”。
您是否正在构建一个应用程序来加密军用级安全系统的信息或身份验证?不,甚至没有关闭。
如果您打算将密码存储在源代码中并因此可执行,那么您只能依赖一种类型的安全性,而安全性是默认。
如果您的问题是您不能或不会将密码存储在源代码中,那么将其移动到单独的dll中什么都不解决,您只需将问题移到另一个项目中。
然而,我想知道一些事情。你说“我必须默认一些东西”。是吗?您是否尝试在源代码中存储安全密码字符串的默认值? “THISISNOTAPASSWORD”怎么样?
答案 2 :(得分:6)
Eric Lippert的You Want Salt With That?(original blog post)
另请阅读他的帖子Use the right tool for the job,并以下列提示结束:
0)如果可能的话,根本就不去那里。加密是非常难以正确的,并且通常是首先是错误的解决方案。使用其他技术来解决您的安全问题。
1)如果问题是不值得信任的客户端,那么就不要构建一个需要信任客户端的安全解决方案。
2)如果您可以使用现成的零件,那么就这样做。
3)如果您不能使用现成的部件并且必须使用密码系统,那么请不要使用您不完全理解的密码系统。
4)如果你必须使用一个你不完全理解的密码系统,那么至少不要用它来解决它不能解决的问题。
5)如果你必须使用密码系统滑过树木,那么至少不要让可能是恶意的客户选择加密的消息。自己选择令牌。如果令牌必须包含来自客户端的信息,则以某种方式对其进行清理;要求它只是直接的ASCII文本,插入随机空格等等。
6)如果您必须允许客户端选择令牌,则不要加密令牌本身。签署令牌的加密安全散列。攻击者更难以选择产生所需哈希的令牌。
7)不要使用相同的密钥对来加密外发邮件,就像保护传入邮件一样。为您将要执行的每个逻辑上不同的操作获取密钥对。
8)双向加密通信。
9)考虑使用撤销机制,这样一旦你知道Eve正在攻击你,你至少可以撤销她的执照。 (或者您可以撤销已知的已被入侵的许可证,依此类推。)
答案 3 :(得分:2)
securing SQL connection strings上的这篇文章应该适用于存储加密密码,让操作系统为您的解密处理盐析种子的加密。
答案 4 :(得分:2)
听起来我可能应该使用PKI解决方案而不是加密/解密。如果您有另一个需要使用加密数据的应用程序,那么您可以拥有该应用程序的密钥对,并将公钥提供给正在进行加密的应用程序。这样你仍然可以保证数据的安全,但不会引入一堆额外的代码,这些代码最终不能提供那么多的保护。
快速谷歌搜索给了我this代码项目文章,讨论在.Net中使用Windows证书存储