几年前,当我第一次接触ASP.net和.NET Framework时,我构建了一个非常简单的在线文件存储系统,该系统使用Rijndael加密技术将加密的文件存储在服务器硬盘上,并使用HttpHandler解密这些文件并将其发送到客户机。
作为www.example.com和数据库的第一个项目之一ASP.net,我对整个项目的工作原理了解不多(也不太了解same trap described by Jeff Atwood on this subject),我决定将新生成的键和IV与数据库中的每个文件条目一起存储。
为了让事情更清楚一点,加密只是为了保护文件不被直接访问服务器,密钥不是由用户输入的密码生成的。
我的问题是,假设我不想为所有文件保留一个密钥,那么我***应该***如何存储加密密钥以获得最佳安全性?什么是最佳实践?(例如:在不同的服务器上,在加密的纯文本文件上)。
另外,在这种类型的加密算法中,初始化向量是用来做什么的?它在系统中应该是常数吗?
4条答案
按热度按时间r7knjye21#
密钥应该被保护和保密,就这么简单。实现却不是。密钥管理系统被值得信赖的供应商以高价出售,因为解决这个问题是困难。
你当然不想对每个用户使用相同的密钥,一个密钥使用得越多,就越容易被破解,或者至少会有一些信息泄露。AES是一种分组密码,它将数据分成块,并将上一个块加密的结果馈送到下一个块。初始化向量是算法的初始馈送,因为在起点没有什么可以开始的。使用具有相同密钥的随机IV降低了信息泄漏的风险-对于每一个加密的数据片段应该是不同的。
你如何存储密钥取决于你的系统是如何架构的。我刚刚完成了一个KMS,其中密钥远离主系统,加密和解密的函数通过WCF公开。你发送纯文本,并获得对密钥的引用和返回的加密文本-这样KMS就负责系统中的所有加密。这对你来说可能有点过头了。如果用户在系统中输入密码,那么您可以使用该密码生成密钥对,然后使用该密钥对加密该用户的密钥存储- XML、SQL等,并使用该密钥对解密用于保护数据的每个密钥。
如果不了解更多关于您的系统是如何配置的,或者它的用途,除了“必须保护密钥,密钥和IV必须不被重用”之外,很难推荐任何其他东西。
rt4zxlrg2#
在http://web.archive.org/web/20121017062956/http://www.di-mgt.com.au/cryptoCreditcard.html上有一篇关于这篇文章的非常好的文章,它涵盖了IV和盐化问题以及上面提到的ECB的问题。
诚然,它仍然没有完全涵盖“我在哪里存储密钥”,但在阅读和消化它之后,希望它不会是一个巨大的飞跃。
7fyelxc53#
作为一个很好的解决方案,你可以将你的Key/IV对存储在一个表中:
保存加密值时,请沿着保存ID和随机Salt值。
然后,当您需要解密该值时,使用与数据一起存储的id和salt查找密钥/iv对。
您需要确保密钥存储的安全模型良好。如果您使用SQL Server,请不要向从应用程序访问数据库的用户授予SELECT权限。您不希望给予某人访问整个表的权限。
ryevplcw4#
如果,你只是为每个用户生成一个密钥,然后用“主密钥”加密它呢?然后,确保有随机的iv,只要你把主密钥保密,没有人应该能够利用任何数量的密钥。当然,加密和解密功能必须在服务器端,以及主密钥不被暴露 * 在所有 *。甚至对服务器的其他部分也不是。这将是一个体面的方式去做,但显然,有一些问题,即,如果你不安全地存储了你的主密钥,那么你的安全就去了。当然,你可以加密主密钥,但然后你只是踢了可以在路上。也许,你可以有一个AES密钥,用RSA密钥加密,然后RSA密钥由一个秘密密码保护,这将缓解问题,就像如果你有一个大小合适的RSA密钥,你应该很好,然后你可以向客户端公开加密函数(尽管仍然可能不应该),并且由于密钥加密使用公钥,因此您可以获取公钥。为了增加安全性,如果需要的话,你可以每几个月甚至几个星期循环一次RSA密钥。这只是一些想法,我知道它不是防弹的,但是比仅仅把它塞进SQL数据库要安全得多。