【问题标题】:Set ACL on private key in HSM在 HSM 中的私钥上设置 ACL
【发布时间】:2021-04-26 19:35:26
【问题描述】:

在 Windows Server A 上,我们可以在 HSM 中生成一个密钥,并将其提供给 AD CS。该密钥用于生成由公共 CA 签名的 CSR,并导入到同一主机上的证书存储中。可以使用 certutil -repairstore 将签名的证书链接到私钥,并使用密钥对工件进行签名。

问题是私钥资源上面有ACL,如果我们移动到服务器N,并尝试在HSM中使用签名密钥,由于密钥上的ACL,会出现权限错误事件无法识别访问它的环境。

Powershell 工具 Get-Acl 和 Set-Acl(在服务器 A 上调用)似乎可以更改 ACL,但我不知道需要哪些参数、参数中应该包含哪些内容以及这些信息的方式应该格式化。也就是说,Get-Acl 的文档说

由于文件系统和注册表提供程序都支持Get-Acl,您可以使用Get-Acl查看文件系统对象的ACL,例如文件和目录,以及注册表 对象,例如注册表项和条目。

(由我突出显示的斜体文本)

那么,Get-Acl 是否正确?还是有其他方法可以使用?

如果有人这样做过,我们可以得到一些指导吗?

HSM 中有一个密钥:

------------------------------------------------------------

Provider          : Utimaco CryptoServer Key Storage Provider
Device            : 3001@127.0.0.1
Group             : utimaco
Mode              : Internal Key Storage

------------------------------------------------------------

Index  AlgId        Size   Group            Name                             Spec
---------------------------------------------------------------------------------
1      RSA          2048   utimaco          testacl                          0

Get-Acl -inputobject 可能让我可以访问该对象,但如何以 InputObject 满意的方式对其进行格式化?

感谢您的任何提示。如果您包含“改为执行此操作”,将很乐意接受“不起作用”。如果这就是你所说的,那么会不高兴地接受是行不通的:)

【问题讨论】:

    标签: windows acl cng


    【解决方案1】:

    Get-Acl/Set-Acl 通常不适用于 CNG 密钥。您既不能使用 -Path 因为没有 PowerShell provider 用于与证书相反的加密密钥,也不能使用 -InputObject 因为加密密钥没有特殊的 PowerShell 对象并且 System.Security.Cryptography.CngKey 没有 GetSecurityDescriptor方法,即called by Get-Acl internally

    IMO 你必须使用 .NET 类来完成这项工作:

    # open provider and key, get security descriptor
    $cngProvider = New-Object System.Security.Cryptography.CngProvider("Utimaco CryptoServer Key Storage Provider")
    $cngKey = [System.Security.Cryptography.CngKey]::Open("testacl", $cngProvider)
    $cngProp = $cngKey.GetProperty("Security Descr", [System.Security.Cryptography.CngPropertyOptions]::None)
    $rawSD = New-Object System.Security.AccessControl.RawSecurityDescriptor($cngProp.GetValue(), 0)
    
    # example: add full access for "NetworkService" at the end of the ACL
    $sid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::NetworkService, $null)
    $accessRead = 0x80020001
    $accessFull = 0xd01f0003
    $newACE = New-Object System.Security.AccessControl.CommonAce([System.Security.AccessControl.AceFlags]::None, [System.Security.AccessControl.AceQualifier]::AccessAllowed, $accessFull, $sid, $false, $null)
    $rawSD.DiscretionaryAcl.InsertAce($rawSD.DiscretionaryAcl.Count, $newACE)
          
    # finally save the modified security descriptor
    $rawSDbin = New-Object 'byte[]' $rawSD.BinaryLength
    $rawSD.GetBinaryForm($rawSDbin, 0)
    # 4 is DACL_SECURITY_INFORMATION, which is not available in the CngPropertyOptions enumeration
    $daclPropertyOptions = [System.Security.Cryptography.CngPropertyOptions]4
    $cngProp = New-Object System.Security.Cryptography.CngProperty("Security Descr", $rawSDbin, $daclPropertyOptions)
    $cngKey.SetProperty($cngProp)
    

    您还可以使用 $rawSD.DiscretionaryAcl.RemoveAce(position) 从 ACL 中删除条目

    【讨论】:

    • 简洁的回答,谢谢!我无法解析的唯一部分(不是 .NET 用户)是“$daclPropertyOptions =”行;不确定 4 是数组中的位置还是大小声明。明天我会研究一下(学习很好),但如果您可以发表评论以解释该行的目的,它可以改善答案。我不知道它是功能性的还是快捷方式?
    • 在代码中添加了注释。有关 DACL_SECURITY_INFORMATION 的信息,请参阅 CNG API 规范docs.microsoft.com/en-us/windows/win32/api/ncrypt/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 2015-07-07
    相关资源
    最近更新 更多