Я создал контейнер RSA Machine Store в качестве не-администратора и назначил полный контроль для себя, а также доступ для чтения к другим учетным записям.
Я хочу иметь возможность программно просматривать ACL для контейнера ключей. Когда я пытаюсь сделать это с помощью кода ниже, я получаю следующее исключение, даже если я являюсь владельцем контейнера ключей и имею полный контроль:
System.Security.AccessControl.PrivilegeNotHeldException: The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.
at System.Security.AccessControl.Privilege.ToggleState(Boolean enable)
at System.Security.Cryptography.Utils.GetKeySetSecurityInfo(SafeProvHandle hProv, AccessControlSections accessControlSections)
at System.Security.Cryptography.CspKeyContainerInfo.get_CryptoKeySecurity()
...
Я могу просматривать привилегии с помощью проводника Windows или CACLS для просмотра ключевого файла в C:\Documents and Settings\All Users\...\Crypto\RSA\MachineKeys
, поэтому кажется, что моя учетная запись имеет необходимые привилегии.
Код, который я использую, выглядит следующим образом:
CspParameters cp = new CspParameters();
cp.Flags = CspProviderFlags.NoPrompt | CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore;
cp.KeyContainerName = containerName;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp))
{
// PrivilegeNotHeldException thrown at next line while
// dereferencing CspKeyContainerInfo.CryptoKeySecurity
if (rsa.CspKeyContainerInfo.CryptoKeySecurity != null)
{
foreach (CryptoKeyAccessRule rule in rsa.CspKeyContainerInfo.CryptoKeySecurity.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
{
... process rule
}
}
}
Здесь вопрос с аналогичной проблемой здесь, но я не вижу никакого способа применить ответ к моей ситуации.
В соответствии с MSDN свойство CspKeyContainerInfo.CryptoKeySecurity
:
Получает объект CryptoKeySecurity, который представляет права доступа и правила аудита для контейнера.
Я хочу объект, представляющий права доступа, но не правила аудита (поскольку у меня нет привилегии для правил аудита).
UPDATE
Я нашел обходное решение, которое заключается в том, чтобы найти файл, содержащий контейнер ключей, и проверить его ACL. Я не совсем этому доволен, так как это зависит от недокументированной реализации деталей криптографических классов (например, предположительно, не будет работать над Mono), и все равно будет интересоваться лучшим решением.
... Initialize cp as above
CspKeyContainerInfo info = new CspKeyContainerInfo(cp);
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"Microsoft\\Crypto\\RSA\\MachineKeys\\" + info.UniqueKeyContainerName);
FileSecurity fs = new FileInfo(path).GetAccessControl(AccessControlSections.Access);
foreach (FileSystemAccessRule rule in fs.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
{
... process rules
}