我们有一个表格,我们保存用户/密码和其他一些数据。每条记录的密码字段都必须加密。我们决定使用 AesCryptoServiceProvider 进行加密,并手动创建了一次 rgbKey。然后加密所有用户密码并将记录插入到我们的表中,其中密码字段使用我们的 rgbKey 加密。
我们在负载均衡器后面有几台服务器,每台服务器都应该读取这些记录并可以解密密码字段值。一开始我们将base64StringFormat中的rgbKey放入我们的dll(API)中,同样所有的服务器都将使用这个API并且可以解密加密的值。
但是,将 rgbKey 保存在 dll 文件中是非常不安全的。我们讨论了是否将密钥保留在 DPAPI 中。在解密时,在我们的任何服务器上,我们将从 DPAPI 获取我们的密钥并成功解密加密值。
我认为我可以在具有当前用户模式的任何服务器中生成一次受保护的密钥,然后将其保存在我们的通用 dll 中。每个使用公共 dll 的服务器,将这个受保护的密钥(字节 [])提供给具有相同用户的 DPAPI,可以获得不受保护的密钥值。但是它只在受保护的机器上工作,在其他机器上它给出错误:“密钥在指定状态下无效。”
我的问题是如何保护我的永久 rgbKey 以便我可以从所有机器访问它?看看下面类似的测试控制台应用程序,我的方法有什么问题?
我为我的测试控制台应用程序提供了一个示例代码:
首先,我在本地机器上运行我的 PDPAPI() 函数:
static void PDPAPI() {
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] rgbKey = encoding.GetBytes( "MyRgbKey" );
byte[] protectedData = ProtectedData.Protect( rgbKey, null, DataProtectionScope.CurrentUser );
string base64ProtectedData = Convert.ToBase64String( protectedData );
Console.WriteLine( "base64ProtectedData:{0}", base64ProtectedData );
}
然后硬编码添加到我的 UDPAPI() 函数 base64ProtectedData 从上述执行中获得的值,重建解决方案:
static void UDPAPI() {
string base64ProtectedData = "****";
byte[] protectedData = Convert.FromBase64String( base64ProtectedData );
byte[] unProtectedData = ProtectedData.Unprotect( protectedData, null, DataProtectionScope.CurrentUser );
string base64unProtectedData = Convert.ToBase64String( unProtectedData );
Console.WriteLine( "base64unProtectedData:{0}", base64unProtectedData );
}
现在,如果我在本地机器上运行 UDPAPI() 函数,它会成功取消保护数据,但是如果我将控制台应用程序迁移到任何其他服务器,并使用我的网络用户登录该服务器,控制台应用程序会给出错误“密钥无效在指定状态下使用。”。