.Net加密例外情况“;“对象已存在”;在蔚蓝上

.Net加密例外情况“;“对象已存在”;在蔚蓝上,.net,azure,cryptography,azure-web-app-service,cryptographicexception,.net,Azure,Cryptography,Azure Web App Service,Cryptographicexception,我们在Azure上的两个web应用程序上部署了一个网站:生产版和预生产版 网站在特定时间使用以下代码创建一个容器来承载RSA密钥: // ----------------------------- // Part 1 : Initialize csp params // ----------------------------- const int PROVIDER_RSA_FULL = 1; const string CONTAINER_NAME = "OurKeyContainer"; Cs

我们在Azure上的两个web应用程序上部署了一个网站:生产版和预生产版

网站在特定时间使用以下代码创建一个容器来承载RSA密钥:

// -----------------------------
// Part 1 : Initialize csp params
// -----------------------------
const int PROVIDER_RSA_FULL = 1;
const string CONTAINER_NAME = "OurKeyContainer";
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";

// --------------------------------------------------
// Part 2 : A try to set folder access rights to "everyone"
// --------------------------------------------------
// http://whowish-programming.blogspot.fr/2010/10/systemsecuritycryptographycryptographic.html
// http://stackoverflow.com/questions/5013881/c-sharp-how-do-i-get-the-everybody-user
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var rule = new CryptoKeyAccessRule(sid, CryptoKeyRights.FullControl, AccessControlType.Allow);
cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);

return new RSACryptoServiceProvider(cspParams);
问题是,这段代码只适用于其中一个网站,即第一个真正启动的网站。第二个抛出了加密异常“对象已存在”

谷歌搜索后,问题似乎是由执行网站的用户没有访问密钥容器的权限造成的,但不幸的是,建议的修复(在上面代码的第2部分中实现)不起作用

有什么想法或建议吗

谢谢


Riana

我认为问题在于,您基本上是在尝试两次创建具有相同名称的机器范围的容器。我假设
pre-prod
prod
环境在同一台机器上,可能是作为应用程序服务中的部署槽?我至少可以用这个设置复制你的问题。我想还有其他一些设置可能会产生相同的情况,但这是最有可能的

在此设置中,您可以更改三项内容,以产生不同的结果:

  • 授予访问权限的标识
  • 货柜店
  • 容器名称
对于标识,我们可以使用
Everyone
(如您所尝试的)或
Current
,我们可以从WindowsIdentity获取这些信息

private IdentityReference GetWindowsIdentity()
{
返回System.Security.Principal.WindowsIdentity.GetCurrent().User;
}
私有标识引用GetEveryoneIdentity()
{
返回新的SecurityIdentifier(WellKnownSidType.WorldSid,null);
}
容器存储可以是
机器范围的
,也可以仅针对当前用户

//机器范围的存储
var cspParams=新的CspParameters(提供程序\u RSA\u已满)
{
...
Flags=CSProviderFlags.UseMachineKeyStore;
...
};
//默认存储
var cspParams=新的CspParameters(提供程序\u RSA\u已满)
{
...
Flags=CSProviderFlags.UseDefaultKeyContainer;
...
};
对于商店名称,我们可以选择一些,在您的情况下,您可以选择相同的名称,但我们也可以为标识设置唯一的名称

KeyContainerName=“OurKeyContainer”,
KeyContainerName=$“OurKeyContainer-{identity}”,
不同的组合将产生不同的结果:

所有人标识、计算机范围存储、相同容器名称在其中一个插槽上失败,原因是
System.Security.Cryptography.Cryptography异常:对象已存在。

每个人标识、机器范围的存储、每个标识的容器确定

每个人标识、用户存储、相同容器名称在两个插槽上都失败,出现
System.Security.Cryptography.Cryptography异常:系统找不到指定的文件。

每个人标识、用户存储、每个标识的容器确定

当前标识、计算机范围存储、相同容器名称在其中一个插槽上失败,原因是
System.Security.Cryptography.cryptographyException:对象已存在。

当前标识、机器范围存储、每个标识的容器正常

当前标识、用户存储、相同容器名称在两个插槽上均失败,出现
System.Security.Cryptography.Cryptography异常:系统找不到指定的文件。

当前标识、用户存储、每个标识的容器在两个插槽上都失败,出现
System.Security.Cryptography.Cryptography异常:系统找不到指定的文件。

因此,总而言之,更改容器的名称以包含环境特有的内容将解决此问题。它不一定是标识(但您在计算机上运行的每个应用程序服务都会获得一个标识,因此相当安全),如果您在应用程序服务中将其设置为
环境变量,并确保分别将其设置为
pre prod
prod
,则它可以是环境的名称


您是否尝试通过KUDU查找失败web应用的身份?你可以找到Aspnet_regais.exe文件的位置。你好,布鲁斯,谢谢你的回复。我阅读了您发送的url,但是Azure控制台和Kudu都无法识别aspnet_regais命令。。有什么建议吗?对于.NET Framework版本4(32位系统),您可以通过KUDU将目录更改为
D:\Windows\Microsoft.NET\Framework\v4.0.30319
,对于.NET Framework版本4(64位系统),您可以将目录更改为
D:\Windows\Microsoft.NET\Framework64\v4.0.30319
。我成功运行了¨它告诉我它成功了,然后我重新启动了我的网站。。但不幸的是,我仍然有同样的例外-(.嗨,非常感谢你花时间做所有这些测试!我只是想知道使用许多不同的密钥容器来承载同一个密钥可能有什么缺点?这取决于你是否想/需要从其他来源使用它们?我认为一个好的分隔符可以是每个环境。我不确定可能有什么缺点,我想我认为这在很大程度上取决于您如何使用容器以及在其中存储的内容。但是(目前)我看不出每个环境/机器密钥至少有一个容器有任何真正的缺点。