Я использую следующий код в попытке программно позволить учетной записи 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 из кода?
Похоже, вы не звоните Персисту. Изменения, которые вы вносите в 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);