Я пытаюсь автоматизировать развертывание сертификатов, включая управление разрешениями на закрытый ключ. Используя этот вопрос, я собрал код, который должен обновлять разрешения для сертификата:
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 "Набор ключей не существует".
По опыту я знаю, что обычно это означает, что текущий контекст безопасности не имеет разрешений на доступ к первичному ключу. Чтобы устранить эту возможность, я сделал следующее:
- Выясните, что представляет собой текущий пользователь, с помощью
System.Security.Principal.WindowsIdentity.GetCurrent()
в окне Immediate. - Убедитесь, что у этого пользователя есть разрешение на полный доступ в оснастке MMC для сертификатов (и дважды проверьте, что я ищу для него нужное хранилище)
- Предоставлен полный доступ пользователю Everyone.
- Попытался создать объект CspParameters с KeyPassword и без него (вы можете увидеть его там в комментариях).
У меня нет идей. Сертификат является поддельным самозаверяющим тестовым сертификатом, поэтому это не вопрос отсутствия разрешений для других сертификатов в цепочке. Любая помощь будет оценена по достоинству.
ОБНОВИТЬ:
Я смог заставить этот код выполняться, изменив некоторые флаги для установки сертификата, который предшествует этому шагу. Теперь код выполняется, по-видимому, успешно, но никакого видимого эффекта я не вижу в MMC.