我正在使用以下代码尝试以编程方式允许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列表?
答案 0 :(得分:10)
您似乎没有调用Persist。您对CryptoKeySecurity所做的更改实际上并未立即保存。您需要使用 Persist(...)
方法之一来实际保存更改。
<击> NativeObjectSecurity.Persist Method (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);
答案 1 :(得分: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))
{
}
}