2010-01-10 320 views
7

几年前,当第一次被引入到ASP.net和.NET Framework时,我构建了一个非常简单的在线文件存储系统。 该系统使用Rijndael加密来存储服务器硬盘上加密的文件,并使用HttpHandler解密并将这些文件发送给客户端。AES加密和密钥存储?

作为我的第一个使用ASP.net和数据库的项目之一,我并不十分了解整个系统是如何工作的(以及落入same trap described by Jeff Atwood on this subject),所以我决定将新生成的密钥和IV与每个文件项在数据库中。

为了使事情更清楚一点,加密只是为了防止文件直接访问服务器,并且密钥不是由用户输入的密码生成的。

我的问题是,假设我不希望保留的所有文件的一个关键,如何应该我存储加密密钥为安全起见?什么被认为是最佳实践? (即:在不同的服务器上,在纯文本文件上加密)。

此外,这种类型的加密算法中使用的初始化向量是什么?它应该在系统中保持不变吗?

回答

11

钥匙应该受到保护并保密,就这么简单。实施不是。密钥管理系统通过值得信赖的供应商大量出售,因为解决问题的办法是hard

你肯定不想为每个用户使用相同的密钥,使用的密钥越多,破解它的“更容易”,或至少有一些信息泄漏。 AES是分组密码,它将数据分成块并将最后一次块加密的结果输入到下一个块中。初始化向量是算法的初始入口,因为在起始点没有任何开始。使用具有相同密钥的随机IV可以降低信息泄露的风险 - 对于加密的每一个数据应该是不同的。

存储密钥的方式取决于系统的架构。我刚刚完成了一个KMS,其中的密钥远离主系统,加密和解密的功能通过WCF公开。您发送纯文本并获得对密钥和加密文本的引用 - 这样KMS就负责系统中的所有加密。这可能在你的情况下是矫枉过正的。如果用户在您的系统中输入密码,那么您可以使用它来生成密钥对。然后可以使用该密钥对该用户的密钥存储进行加密 - XML,SQL等,并用于解密用于保护数据的每个密钥。

不知道更多关于如何配置系统的信息,或者目的很难推荐除“密钥必须被保护,密钥和IV不能重复使用”以外的任何其他信息。

+2

次要观察:“AES是一个分组密码,它将数据分成块并将最后一个块加密的结果送入下一个块。”您正在描述[CBC](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29)* a *安全使用AES的方法。还有其他安全的解决方案 - 并不都需要一个初始化向量。 – KovBal 2014-10-14 16:55:39

3

作为一个很好的soltution,你可以存储你的密钥/ IV对一个表:

ID     Key   IV 
skjsh-38798-1298-hjj FHDJK398720== HFkjdf87923== 

当您保存加密值,保存ID,并与它一起随机盐值。

然后,当您需要解密该值时,使用id和盐与数据一起存储来查找key/iv对。

你想确保你的密钥存储周围有一个很好的安全模型。如果使用SQL服务器,请不要将SELECT权限授予从应用程序访问数据库的用户。你不想让某人访问整个桌子。

+3

如果您将SQL服务器本身定义为固有安全并将密钥存储在其中以满足您的安全需求,那么这是一个非常好的解决方案。这可以通过在sql server上启用透明数据加密来进一步消除,以防止有人将DB从服务器复制出去,或物理上让硬盘绕过所有软件访问控制。 – 2010-01-11 15:36:05

3

http://web.archive.org/web/20121017062956/http://www.di-mgt.com.au/cryptoCreditcard.html上有一篇非常好的文章,其中涵盖了IV和盐析问题以及上述ECB的问题。

它仍然没有完全覆盖“我在哪里存储密钥”,无可否认,但阅读和消化之后,它不会是一个巨大的飞跃,希望能解决....

+1

已损坏的文章链接 – CodeClimber 2013-08-01 15:12:00

+0

2年前的答案和我无法控制的域名。时间使用互联网存档Wayback机器.... – 2013-08-05 12:09:40

+2

对于懒惰的 - http://web.archive.org/web/20121017062956/http://www.di-mgt.com.au/cryptoCreditcard.html – 2013-08-05 13:55:42