从Windows密钥库安全地处理私钥

| 我正在开发一个对ASP.Net Web服务器的配置文件设置进行加密的应用程序。我正在实现的加密方法是使用AES和RSA封装数据。我正在生成一个AES密钥,使用该AES密钥对我的数据进行加密,然后使用Windows证书存储区中的证书中的公共密钥对AES密钥进行加密。然后,我将数据以及加密的AES密钥以及用于加密的证书序列号保存回配置文件。 当我想访问此数据时,我读取用于加密AES密钥的证书的序列号,从该证书中取出私钥,然后解密AES密钥,然后使用该密钥解密数据。这是我不确定自己的安全级别的地方。 为了访问与证书关联的私钥,我必须将私钥标记为可导出,并为用户提供我的应用程序在对私钥的访问权限下运行。由于这是ASP.Net服务器,因此该用户为\“网络服务\”。我敢肯定,您会明白为什么这将是一个安全问题。基本上,如果有人通过某种方式侵入Web上的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);
}
谢谢。     
已邀请:
只是写
RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)decryptionCertificate.PrivateKey
这并不意味着您要分配实际的“键”。您可以将私钥设为“不可导出”,并且仍然可以执行解密。     
如果您拥有带有私钥的证书,则对AES密钥采用PKCS#7 / CMS加密是有意义的。这使您可以使用不可导出的私钥解密数据。 不幸的是,.NET似乎没有提供用于CMS加密的类。 CryptoAPI确实提供了此类功能(CryptEncryptMessage和CryptDecryptMessage),但是它们需要通过P / Invoke进行调用,这在某种程度上是不平凡的。有关执行此操作的C#示例,请参见此处的源代码。 另一种选择是使用我们的SecureBlackbox组件(TElMessageEncryptor,TElMessageDecryptor),尽管在您的情况下这可能是一个过大的选择。     
我认为您的安全模型存在一些固有的冲突。您希望在“网络服务”用户下运行的应用程序能够解密配置文件,但是即使“网络服务”用户受到威胁,您也希望加密信息安全。这两个目标是矛盾的-用户可以访问数据还是不能访问数据。我认为最好的办法是隔离安全性访问权限,这样一台计算机上的“网络服务”就会受到影响,而不会损害其他用户或其他计算机的安全性。这就是Windows安全模型为每台计算机上的每个用户提供自己的私钥的原因,而这就是DPAPI用来加密/解密配置文件的密钥。 您说在模型中,您正在使用一组标准密钥来加密配置信息。在此模型中,如果一台计算机上的一个受信任用户受到威胁,则攻击者将获得密钥,以访问所有计算机上所有用户的所有加密配置数据。您说如果机器发生故障,您将使用托管密钥。我建议备份和管理要加密的数据比备份和管理用于访问该数据的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)如果将任何重要的数据放入配置文件中,并且在机器故障的情况下需要恢复,则发送该数据数据备份到数据库或其他中央数据存储中。这样可以避免对所有部署使用相同的一个或多个托管密钥。     
有人对我如何使模型更安全有任何建议吗? 您的说法是正确的,因为在网络服务下运行的任何服务都可能会访问私钥。在2005年左右的某个时候,Microsoft意识到了这一点,并开始创建唯一的服务帐户以限制损坏,从而导致常见的服务受损,例如Network Services。例如,SQL Server已移至其自己的服务帐户IIRC。 根本的问题是Microsoft模型的安全性设计问题,您可以做很多事情。微软意识到了这一点,并使用CryptoNG IIRC转移到一个略有不同的模型。在CryptoNG下,使用私钥的操作是进程外的,而IPC用于在服务与执行密钥操作的进程之间来回传递请求和结果。这主要是避免您所关心的问题。 即使在新模型下,您仍然需要能够识别该模型的软件。您应该可以说IIS 7,但是Apache可能会引起问题,因为它的模型只能识别文件系统ACL。 将关键操作移出流程已成为一种标准做法。例如,GnuPG会执行相同的操作。 GnuPG使用一个名为libassuan的库,该库在消费者和生产者之间执行请求和结果的封送处理。 我不会太担心进程外模型中客户端和服务器之间的效率问题。 Windows管道,Unix管道和Unix域套接字正在迅速减轻。同样,它就像乔恩·本特利(Jon Bentley)博士说的那样:如果不一定要正确,我可以按照您希望的那样快速完成。     

要回复问题请先登录注册