从Windows密钥库安全处理私钥

时间:2011-05-06 14:53:05

标签: c# security cryptography private-key x509

我正在开发一个加密ASP.Net Web服务器配置文件设置的应用程序。我正在实现的加密方法是使用AES和RSA封装数据。我正在生成一个AES密钥,使用该AES密钥加密我的数据,然后使用我的Windows证书存储区中的证书中的公钥加密AES密钥。然后,我将数据以及加密的AES密钥和用于加密它的证书序列号保存回配置文件。

当我想访问此数据时,我读取用于加密AES密钥的证书的序列号,从该证书中提取私钥,并解密AES密钥,然后使用该密钥解密数据。这是我不确定我的安全水平的地方。

为了访问与证书关联的私钥,我必须将私钥标记为可导出,并在用户访问私钥的情况下运行我的应用程序。由于这是一个ASP.Net服务器,该用户是“网络服务”。我相信你能明白为什么这会是一个安全问题。基本上如果有人通过网络闯入我的ASP.Net服务器,可能通过某种注入,他们可以访问该私钥,不是吗?

有没有人对如何让我的模型更安全有任何建议?

解密功能:

//need an rsa crytpo provider to decrypt the aes key with the private key associated with the certificate
using (RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider) decryptionCertificate.PrivateKey)
{
    //decrypt the aes key with the cert's private key
    byte[] aesKey = rsaCSP.Decrypt(encryptedAESKey, false);

    //decrypt data using the decrypted aes key and the IV passed in
    decryptedData = decryptWithAes(encryptedData, aesKey, aesIV);
}

感谢。

4 个答案:

答案 0 :(得分:2)

只需写下

RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)decryptionCertificate.PrivateKey

这并不意味着您要分配实际的“密钥”。您可以使私钥不可导出,仍然可以执行解密。

答案 1 :(得分:1)

如果您的证书带有私钥,则使用AES密钥的PKCS#7 / CMS加密是有意义的。这使您可以使用不可导出的私钥解密数据。

不幸的是,.NET似乎没有提供CMS加密的类。 CryptoAPI确实提供了这样的函数(CryptEncryptMessageCryptDecryptMessage),但它们需要通过P / Invoke调用,这在某种程度上可以是非平凡的。对于执行此see the source code here的C#示例。

另一种选择是使用我们的SecureBlackbox组件(TElMessageEncryptor,TElMessageDecryptor),但在您的情况下,这可能是一种过度杀伤力。

答案 2 :(得分:1)

我认为您的安全模型存在一些固有的冲突。您希望在用户“网络服务”下运行的应用程序能够解密配置文件,但您希望即使“网络服务”用户受到危害,加密信息也是安全的。这两个目标是不一致的 - 用户可以访问数据,也可以不访问。我认为你能做的最好的就是安全访问,这样如果一台机器上的“网络服务”受到损害,它就不会危及其他用户或其他机器的安全。这就是Windows安全模型为每台计算机上的每个用户提供自己的私钥的原因,也就是DPAPI用来加密/解密配置文件的密钥。

您说在您的模型中,您使用一组标准密钥加密配置信息。在此模型中,如果一台计算机上的一个受信任用户受到攻击,则攻击者获得密钥以访问所有计算机上所有用户的所有加密配置数据。您说在机器出现故障时您正在使用托管密钥。我建议备份和管理正在加密的DATA然后备份和管理用于访问该数据的KEYS更安全。

我的建议是使用内置的.Net方法加密/解密配置数据,该方法使用本地计算机上用户的Windows私钥。 (这里有一些实现标准方法的例子:http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx和这里:http://www.codeproject.com/KB/security/ProtectedConfigWinApps.aspx)如果任何数据被放入配置文件中,这些数据是必不可少的,并且在机器出现故障时需要恢复,然后将该数据作为备份发送到您的数据库或其他中央数据存储。这样可以避免为所有部署使用相同的托管密钥。

答案 3 :(得分:0)

  

有没有人对如何让我的模型更安全有任何建议?

您是正确的,因为在网络服务下运行的任何受到危害的服务都可能访问私钥。在2005年左右的某个时候,Microsoft意识到并开始创建独特的服务帐户,以限制因常见受损服务而造成的损害,例如网络服务。例如,SQL服务器已移至其自己的服务帐户IIRC。

根本问题是微软的模型存在安全设计问题,而且你可以用它做很多事情。微软意识到了这一点,并转而采用与CryptoNG,IIRC略有不同的模式。在CryptoNG下,使用私钥的操作是进程外的,IPC用于在服务和执行密钥操作的进程之间来回传递请求和结果。这主要是支持您关注的问题。

即使在新模型下,您仍然需要能够识别模型的软件。你应该没问题,IIS 7,但Apache可能会导致问题,因为它的模型只能识别文件系统ACL。

将进程外的关键操作转移到标准做法。例如,GnuPG也是如此。 GnuPG使用一个名为libassuan的库,它在消费者和生产者之间执行请求和结果的编组。

我不会过分关注进程外模型中客户端和服务器之间的效率问题。 Windows管道,Unix管道和Unix域套接字正在快速发展。此外,它很像Dr. Jon Bentley说: 如果它不是正确的,我可以像你想的那样快速地制作它。