views:

71

answers:

1

I'm using the following code in an attempt to programatically allow the NetworkService account to have access to a key:

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
  )
);

This code runs without error, but has no effect on the key container's permissions.

However, using the commandline tool aspnet_regiis to do the same thing, works perfectly:

aspnet_regiis -pa "MyEncryptionKey" "NetworkService"

I'm running with full admin rights - if I don't run with those rights, then an exception is thrown. I'm also running as the user that initially created the key.

The key container always has the following access rules:

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

With aspnet_regiis, the SID, S-1-5-20 gets added to this list. I can't affect it from code.

I've tried creating the security identifier from the sid in string format, as well as using SetAccessRule instead of AddAccessRule.

Any ideas how to actually affect this ACL list from code?

+3  A: 
jrista
Sadly all the Persist methods are Protected.
Jim T
It looks like you need to modify the security before creating the provider using CspParameters. The CspParameters, when passed to the RSACryptoServiceProvider, invoke a persist. VERY odd way to build an API, but according to the documentation, that seems to be how it works. Answer updated to reflect.
jrista
Jim T
It also helps to add the UseMachineKeyStore flag if you are indeed using a machine key.
Jim T