Our web service wraps around a third party library that contains the following code.
我们的Web服务包含第三方库,其中包含以下代码。
We are using an Active Directory service account in the IIS 6 app pool (no interactive login abilities). Our service fails with the error “The system cannot find the file specified”. We’ve traced the error to the “RSACryptoServiceProvider provider = new RSACryptoServiceProvider();”. The third party assembly depends on a x509 file based certificate for its encryption process and the Service Account has Read / Write access to the keys folder. Additionally, the service account has Read, Write, Modify rights to “C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys”.
我们在IIS 6应用程序池中使用Active Directory服务帐户(没有交互式登录功能)。我们的服务失败,并显示错误“系统找不到指定的文件”。我们已将错误跟踪到“RSACryptoServiceProvider provider = new RSACryptoServiceProvider();”。第三方程序集依赖于基于x509文件的证书进行加密,而服务帐户具有对keys文件夹的读/写访问权限。此外,服务帐户具有“C:\ Documents and Settings \ All Users \ Application Data \ Microsoft \ Crypto \ RSA \ MachineKeys”的读取,写入,修改权限。
Code:
StringBuilder builder = new StringBuilder(publicKeyData);
builder.Replace("-----BEGIN CERTIFICATE-----", "");
builder.Replace("-----END CERTIFICATE-----", "");
X509Certificate2 certificate = new X509Certificate2( Convert.FromBase64String(builder.ToString()));
string xmlString = certificate.PublicKey.Key.ToXmlString(false);
RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); //BOOM
CspKeyContainerInfo containerInfo = provider.CspKeyContainerInfo;
provider.PersistKeyInCsp = false;
provider.FromXmlString(xmlString);
loadedKeys.Add(key, provider);
provider2 = provider;
We cracked open FileMon and noticed that there is a FILE NOT FOUND for that AppPool, followed by another SUCCESS for the same exact file.
我们破解了打开的FileMon并注意到该AppPool有一个FILE NOT FOUND,然后是同一个确切文件的另一个SUCCESS。
I'm out of my element here, anybody have an idea as to why we're seeing this?
我不在这里,任何人都知道我们为什么会看到这个?
2 个解决方案
#1
The reason why you are seeing this is because RSACryptoService provider opens an exclusive lock on the machine key store. It doesn't matter if you are reading the certificate, using the object results in a lock
您之所以看到这一点,是因为RSACryptoService提供程序在计算机密钥存储区上打开了一个独占锁。如果您正在阅读证书,使用对象导致锁定无关紧要
Two ways around it:
两种方式:
- Use non-Microsoft RSA stack.
- use lock() while accessing the object.
使用非Microsoft RSA堆栈。
访问对象时使用lock()。
I ran into the same thing and ended up writing my own RSA set of functions.
我遇到了同样的事情,最终编写了我自己的RSA功能集。
You can also set a user profile affinity in ASP.NET pool; that way a user profile keystore will be used instead
您还可以在ASP.NET池中设置用户配置文件关联;这样就可以使用用户配置文件密钥库
#2
I do not have any idea about what causes the error, but instead of xml-encoding and -decoding the public-key, you could just do:
我不知道导致错误的原因,但是你可以这样做,而不是xml编码和 - 解码公钥。
StringBuilder builder = new StringBuilder(publicKeyData);
builder.Replace("-----BEGIN CERTIFICATE-----", "");
builder.Replace("-----END CERTIFICATE-----", "");
X509Certificate2 certificate = new X509Certificate2( Convert.FromBase64String(builder.ToString()));
RSACryptoServiceProvider provider =
(RSACryptoServiceProvider) certificate.PublicKey.Key;
loadedKeys.Add(key, provider);
provider2 = provider;
If you are lucky, that works-around the error.
如果你很幸运,这可以解决错误。
#1
The reason why you are seeing this is because RSACryptoService provider opens an exclusive lock on the machine key store. It doesn't matter if you are reading the certificate, using the object results in a lock
您之所以看到这一点,是因为RSACryptoService提供程序在计算机密钥存储区上打开了一个独占锁。如果您正在阅读证书,使用对象导致锁定无关紧要
Two ways around it:
两种方式:
- Use non-Microsoft RSA stack.
- use lock() while accessing the object.
使用非Microsoft RSA堆栈。
访问对象时使用lock()。
I ran into the same thing and ended up writing my own RSA set of functions.
我遇到了同样的事情,最终编写了我自己的RSA功能集。
You can also set a user profile affinity in ASP.NET pool; that way a user profile keystore will be used instead
您还可以在ASP.NET池中设置用户配置文件关联;这样就可以使用用户配置文件密钥库
#2
I do not have any idea about what causes the error, but instead of xml-encoding and -decoding the public-key, you could just do:
我不知道导致错误的原因,但是你可以这样做,而不是xml编码和 - 解码公钥。
StringBuilder builder = new StringBuilder(publicKeyData);
builder.Replace("-----BEGIN CERTIFICATE-----", "");
builder.Replace("-----END CERTIFICATE-----", "");
X509Certificate2 certificate = new X509Certificate2( Convert.FromBase64String(builder.ToString()));
RSACryptoServiceProvider provider =
(RSACryptoServiceProvider) certificate.PublicKey.Key;
loadedKeys.Add(key, provider);
provider2 = provider;
If you are lucky, that works-around the error.
如果你很幸运,这可以解决错误。