8

我正在使用以下代码尝试以编程方式允许 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 列表?

4

2 回答 2

10

您似乎没有调用 Persist。您对 CryptoKeySecurity 所做的更改实际上不会立即保存。您需要使用其中一种Persist(...)方法来实际保存更改。

NativeObjectSecurity.Persist 方法(字符串、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);
于 2010-06-29T16:46:51.207 回答
1

我只是想正式确定 Jim T 在评论中所说的内容,因为它对我有用。

//Read the current settings
CspParameters csp = new CspParameters(PROVIDER_RSA_FULL)
{
    KeyContainerName = container,
    Flags = CspProviderFlags.NoPrompt | CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey
};
//Retrieve Current Settings
using (var rsa = new RSACryptoServiceProvider(csp))
{
    var ci = rsa.CspKeyContainerInfo;

    //Create new settings and copy values over
    CspParameters csp2 = new CspParameters(PROVIDER_RSA_FULL)
    {
        KeyContainerName = container,
        Flags = CspProviderFlags.NoPrompt | CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey,
        CryptoKeySecurity = ci.CryptoKeySecurity,
        ProviderName = ci.ProviderName,
        ProviderType = ci.ProviderType
    };
    //Add Permissions
    csp2.CryptoKeySecurity.AddAccessRule(new CryptoKeyAccessRule(securityIdentifier, CryptoKeyRights.FullControl, AccessControlType.Allow));

    //Save settings
    using (var rsa2 = new RSACryptoServiceProvider(csp2))
    {
    }
}
于 2019-02-19T17:17:26.543 回答