我正在尝试自动部署证书,包括管理私钥的权限。使用这个问题,我拼凑了一些应该更新证书权限的代码:
public static SetPermissionsResult SetPermissions(X509Certificate2 certificate, string userName)
{
var account = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null);
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.MaxAllowed);
var newCertificate = store.Certificates.Find(X509FindType.FindBySerialNumber, certificate.SerialNumber, false)[0];
var rsa = newCertificate.PrivateKey as RSACryptoServiceProvider;
if (rsa == null)
{
return SetPermissionsResult.Failure;
}
rsa.PersistKeyInCsp = true;
var cspParams = new CspParameters(
rsa.CspKeyContainerInfo.ProviderType,
rsa.CspKeyContainerInfo.ProviderName,
rsa.CspKeyContainerInfo.KeyContainerName)
{
Flags =
CspProviderFlags.UseExistingKey
| CspProviderFlags.UseMachineKeyStore,
CryptoKeySecurity =
rsa.CspKeyContainerInfo.CryptoKeySecurity,
KeyNumber = (int)rsa.CspKeyContainerInfo.KeyNumber/*,
KeyPassword = password*/
};
cspParams.CryptoKeySecurity.AddAccessRule(
new CryptoKeyAccessRule(account, CryptoKeyRights.GenericRead, AccessControlType.Allow));
using (var rsa2 = new RSACryptoServiceProvider(cspParams))
{
}
return SetPermissionsResult.Success;
}
}
在读取的行上using (var rsa2 = new RSACryptoServiceProvider(cspParams))
(新的加密提供程序被实例化以保持新的访问规则),我得到一个CryptographicException "Keyset does not exist"。
我从经验中知道,这通常意味着当前的安全上下文没有访问主键的权限。为了解决这种可能性,我做了以下事情:
System.Security.Principal.WindowsIdentity.GetCurrent()
在“立即”窗口中找出当前用户的状态- 确保该用户在 MMC 管理单元中对证书具有完全控制权限(并仔细检查我正在查看它的正确存储)
- 授予Everyone用户完全控制权。
- 尝试使用和不使用 KeyPassword 创建 CspParameters 对象(您可以在那里看到它的评论)。
我没主意了。该证书是伪造的自签名测试证书,因此与链中的其他证书缺少权限无关。任何帮助,将不胜感激。
更新:
我已经能够通过在此步骤之前修改一些用于安装证书的标志来执行此代码。现在,代码显然成功执行了,但我在 MMC 中看不到任何可见的效果。