Попытка установить полномочия на KeyContainer в C# не имеет никакого эффекта

Я использую следующий код в попытке программно позволить учетной записи NetworkService иметь доступ к ключу:

var RSA = new RSACryptoServiceProvider(
   new CspParameters() { 
     KeyContainerName = "MyEncryptionKey", 
     Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore 
});

RSA.CspKeyContainerInfo.CryptoKeySecurity.AddAccessRule(
  new System.Security.AccessControl.CryptoKeyAccessRule(
    new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null),
    CryptoKeyRights.GenericAll,
    AccessControlType.Allow
  )
);

Этот код работает без ошибки, но не имеет никакого эффекта на полномочия ключевого контейнера.

Однако с помощью инструмента командной строки aspnet_regiis, чтобы сделать то же самое, работы отлично:

aspnet_regiis -pa "MyEncryptionKey" "NetworkService"

Я работаю с полными правами администратора - если я не работаю с теми правами, затем исключение выдается. Я также работаю как пользователь, который первоначально создал ключ.

Ключевой контейнер всегда имеет следующие правила доступа:

S-1-5-18         -> LocalSystem
S-1-5-32-544     -> Administrators
S-1-5-5-0-135377 -> MyUser

С aspnet_regiis SID, S-1-5-20 добавляется к этому списку. Я не могу влиять на него из кода.

Я попытался создать идентификатор безопасности из sid в формате строки, а также использовать SetAccessRule вместо AddAccessRule.

Какие-либо идеи, как на самом деле влиять на этот список ACL из кода?

7
задан Jim T 29 June 2010 в 16:43
поделиться

1 ответ

Похоже, вы не звоните Персисту. Изменения, которые вы вносите в CryptoKeySecurity, на самом деле не сохраняются сразу. Вам нужно использовать один из методов Persist (...) , чтобы фактически сохранить изменения.

Метод NativeObjectSecurity.Persist (String, AccessControlSections)

Похоже, эти API придерживаются довольно запутанного подхода к модификации. Сначала вам нужно создать CspParameters, применить необходимые изменения, а затем построить поставщик из этих параметров. Конструкция вызывает обновление контейнера.

var params = new CspParameters
{
     KeyContainerName = "MyEncryptionKey", 
     Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore    
};

params.CryptoKeySecurity.AddAccessRule(
  new System.Security.AccessControl.CryptoKeyAccessRule(
    new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null),
    CryptoKeyRights.GenericAll,
    AccessControlType.Allow
  )
);

var RSA = new RSACryptoServiceProvider(params);
10
ответ дан 6 December 2019 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: