【问题标题】:CngKey Assign permission to machine keyCngKey 为机器密钥分配权限
【发布时间】:2018-06-25 08:09:30
【问题描述】:

我创建了一个机器范围的 CngKey (MachineKey=true),但我的应用程序无法访问它。

如何分配权限,以便我的应用程序池可以访问密钥?最好务实,以便我可以将其构建到安装程序中。

Powershell 创建脚本:

[System.Security.Cryptography.CngKeyCreationParameters] $cngKeyParameter =  [System.Security.Cryptography.CngKeyCreationParameters]::new()
    $cngKeyParameter.KeyUsage = [System.Security.Cryptography.CngKeyUsages]::AllUsages
    $cngKeyParameter.ExportPolicy = [System.Security.Cryptography.CngExportPolicies]::AllowPlaintextExport

    $cngKeyParameter.Provider = [System.Security.Cryptography.CngProvider]::MicrosoftSoftwareKeyStorageProvider
    $cngKeyParameter.UIPolicy = [System.Security.Cryptography.CngUIPolicy]::new([System.Security.Cryptography.CngUIProtectionLevels]::None)
    $cngKeyParameter.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::MachineKey

    #Create Cng Property for Length, set its value and add it to Cng Key Parameter
    [System.Security.Cryptography.CngProperty] $cngProperty = [System.Security.Cryptography.CngProperty]::new($cngPropertyName, [System.BitConverter]::GetBytes(2048), [System.Security.Cryptography.CngPropertyOptions]::None)
    $cngKeyParameter.Parameters.Add($cngProperty)

    #Create Cng Key for given $keyName using Rsa Algorithm
    [System.Security.Cryptography.CngKey] $key = [System.Security.Cryptography.CngKey]::Create([System.Security.Cryptography.CngAlgorithm]::Rsa, "MyKey", $cngKeyParameter)

【问题讨论】:

    标签: security encryption cng


    【解决方案1】:

    CNG 密钥的权限有点间接。

    如果您知道要应用的完整权限集,则可以在创建时执行(抱歉,您必须将 C# 转换为 PowerShell):

    CryptoKeySecurity sec = new CryptoKeySecurity();
    
    sec.AddAccessRule(
        new CryptoKeyAccessRule(
            new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
            CryptoKeyRights.FullControl,
            AccessControlType.Allow));
    
    sec.AddAccessRule(
        new CryptoKeyAccessRule(
            new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null),
            CryptoKeyRights.GenericRead,
            AccessControlType.Allow));
    
    const string NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr";
    const CngPropertyOptions DACL_SECURITY_INFORMATION = (CngPropertyOptions)4;
    
    CngProperty permissions = new CngProperty(
        NCRYPT_SECURITY_DESCR_PROPERTY,
        sec.GetSecurityDescriptorBinaryForm(),
        CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION);
    
    cngKeyParameter.Parameters.Add(permissions);
    

    如果您想稍后附加规则(例如在使用默认权限创建规则之后):

    CngProperty prop = key.GetProperty(NCRYPT_SECURITY_DESCR_PROPERTY, DACL_SECURITY_INFORMATION);
    CryptoKeySecurity sec = new CryptoKeySecurity();
    sec.SetSecurityDescriptorBinaryForm(prop.GetValue());
    
    sec.AddAccessRule(
        new CryptoKeyAccessRule(
            new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null),
            CryptoKeyRights.GenericRead,
            AccessControlType.Allow));
    
    CngProperty newProp = new CngProperty(
        prop.Name,
        sec.GetSecurityDescriptorBinaryForm(),
        CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION);
    
    key.SetProperty(newProp);
    

    【讨论】:

    • 感谢 bartonjs。我按照您的建议添加了权限。它执行没有错误。但我仍然无法访问它。我正在使用密钥来加密始终加密的数据库。主加密密钥创建时没有错误,但是当我尝试创建列加密密钥时,我收到以下错误:“打开 Microsoft 加密 API 时发生错误:下一代 (CNG) 密钥:'Microsoft 软件密钥存储提供程序/ CNG_Test'。验证 CNG 提供程序名称“Microsoft Software Key Storage Provider”是否有效,已安装在计算机上,并且密钥“CNG_Test”存在。”
    • @Swifty 听起来像是在寻找用户密钥。但是,如果权限更改现在有效,那么您将进入一个我无法帮助解决的特定于 SqlServer 的问题的领域 - 并且可能会是一个不同的问题。
    • 是的,我相信你是对的。我能够使用您提供的代码来解决问题。它允许我使用网络服务手动打开机器密钥,然后将其副本导入网络服务的密钥库。这不是最好的解决方案,但在 SQL 允许使用机器密钥之前,这是唯一的解决方案。感谢您的帮助。
    • @bartonjs - 使用与上述类似的访问规则时,管理员帐户的访问权限无法删除密钥,即使指定了 FullControl。如果我改为生成密钥,然后使用第二种方法,则该密钥保留了被管理员帐户删除的能力。你知道有什么明显的原因吗?
    • 对于任何试图在 .Net5 中使用该代码的人。您可以将 CryptoKeySecurity/CryptoKeyAccessRule 替换为 FileSecurity/FileSystemAccessRule,只要您使用 Microsoft Software Key Storage Provider(这是默认设置),它就可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 2015-11-17
    • 1970-01-01
    • 2010-11-04
    • 2013-07-23
    • 1970-01-01
    相关资源
    最近更新 更多