gpt4 book ai didi

.net - 所有不同的X509KeyStorageFlags的基本原理是什么?

转载 作者:行者123 更新时间:2023-12-02 09:51:09 27 4
gpt4 key购买 nike

今天,一位同事发现了另一个与此有关的错误!我发现这些标志确实让我感到沮丧,因为如果在实例化X509Certificate2对象,导出它们或将它们保存在X509Store中时,将它们弄得有些错误,则可能会遇到各种奇怪的错误,例如:

  • 意外地不能告诉NETSH.exe或ASP.net [通过其指纹]使用某个SSL证书,即使您的计算机存储中有该证书
  • 意外地,您可以导出证书数据,但是使用.Export()
  • 可以导出没有私钥的数据
  • 意外地是您的单元测试在较新的Windows版本上开始失败,这显然是因为您未使用正确的标记

  • 是的,它们已经全部记录在案了(某些文件似乎很有意义),但是为什么它必须这么复杂?

    最佳答案

    主要是,今天必须如此复杂,因为昨天是如此复杂,而且没有人提出任何更简单的方法。

    我在这里无法提出线性叙述,因此请耐心要求进行来回编织。

    什么是PFX/PKCS#12文件?

    虽然我不能完全说出PFX的起源,但是Windows函数的名称有一个线索可以读写:PFXImportCertStorePFXExportCertStore。它们包含许多单独的实体(证书,私钥和其他东西),可以使用属性标识符进行相互关联。它们似乎被设计为整个证书存储区(如所有CurrentUser\My)的导出/导入机制。但是由于一种存储是“内存存储”(任意集合),因此.NET导入/导出是有意义的,但是会带来一些麻烦(来自.NET之前)。

    Windows私钥

    Windows为私钥支持许多不同的位置,但是对于传统的加密API,它们归结为4部分寻址方案:

  • 密码提供程序的名称
  • key 容器的名称
  • 这是机器相对键还是用户相对键
  • 的标识符
  • 这是“签名” key 还是“交换” key 的标识符。

  • 简化为CNG的3部分方案:
  • 存储引擎的名称
  • key 名称
  • 这是机器相对键还是用户相对键的标识符。

  • 为什么需要机器识别码?

    CAPI和CNG都支持与命名键直接交互。因此,您创建了一个名为“EmailDecryption”的 key 。系统上的另一个用户创建了相同名称的 key 。应该行吗?我们很可能会。所以,真主党,确实如此!单独的 key ,因为它们被保存在与创建它们的用户相关的上下文中。

    但是现在您想要一个可以供多个用户使用的 key 。这不是您通常想要的东西,因此不是默认值。这是一个选择。 CRYPT_MACHINE_KEYSET标志诞生了。

    我将继续在这里说,我听说现在不建议直接使用命名键。 CAPI/CNG团队更喜欢以GUID命名的 key ,并且您可以通过证书存储与它们进行交互。但这是演变的一部分。

    导入PFX有什么作用?

    PFXImportCertStore将所有证书从PFX复制到提供的存储中。它还会导入( CryptImportKeyBCryptImportKey,取决于其认为的需求)。然后,对于它导入的每个 key ,它都会找到(通过PFX中的属性值)匹配的证书,并在证书存储表示中为“这是我的4部分标识符”设置一个属性(CNG key 仅设置了第4个部分为0);这实际上是证书所知道的有关其私钥的全部信息。

    (PFX是一种非常复杂的文件格式,如果没有使用“怪异的部分”,则此描述是正确的)

    关键生命周期

    Windows私钥将永久存在,或者直到有人将其删除为止。

    因此,当PFX导入它们时,它们将永远存在。如果要导入到CurrentUser\My,则这很有意义。如果您只是暂时执行某项操作,则没有意义。

    .NET反转关系/使其变得“太容易”

    Windows设计(大多数情况下)是您与证书库进行交互,并且从证书库获得证书。 .NET后来出现了,并且(一个推论是基于查看应用程序的实际运行情况)将证书作为顶级对象,并存储了一些次要的东西。

    因为Windows证书(实际上是“存储证书元素”)“知道”其私钥是什么,所以.NET证书“知道”其私钥是什么。

    哦,但是MMC证书管理器说它可以将带有其私钥的证书导出到PFX中,为什么证书构造函数不能接受“仅证书”格式之外的字节?好吧,现在可以了。

    协调生命

    您打开一些字节作为X509Certificate/X509Certificate2。这是带有“无密码”的PFX(通过多种可能正确的方式)。您会发现它是错误的,然后将证书交给垃圾收集器。该私钥将永远存在,因此您的硬盘驱动器会慢慢装满,并且 key 存储访问变得越来越慢。然后,您会生气,并重新格式化计算机。

    这似乎很糟糕,所以.NET要做的是,当证书(的一个字段)被垃圾回收(实际上是最终确定)时,它告诉CAPI(或CNG)删除 key 。现在事情按预期进行了,对不对?好吧,只要程序没有异常终止。

    哦,您将其添加到了持久存储中?但是,在新的证书存储实体“知道”如何找到私钥之后,我将删除私钥。好像不好

    输入 X509KeyStorageFlags.PersistKeySet
    PersistKeySet说“不要执行删除操作”。适用于打算将证书添加到X509Store的情况。

    如果要在不指定标志的情况下进行相同的操作,请在导入后调用 Environment.FailFast或拔出计算机的电源。

    关于机器或用户位

    在.NET中,您可以轻松地在集合中保存证书包,并在其上调用 Export。如果有些具有机器 key ,而另一些具有用户 key 怎么办? PFXExportCertStore可以解救。导出机器 key 时,它会写下一个标识符,说它是机器 key ,因此导入会将其放回原处。

    好吧,通常。也许您从一台机器上导出了机器 key ,而您只是想以非管理员身份检查另一台机器上的 key 。好的,您可以指定 CRYPT_USER_KEYSETX509KeyStorageFlags.UserKeySet

    哦,您是在一台计算机上以用户身份创建的,但又希望将其作为另一台计算机上的计算 secret 钥吗?美好的。 CRYPT_MACHINE_KEYSET/ X509KeyStorageFlags.MachineKeySet

    我真的需要“临时”文件吗?

    如果您只是检查PFX文件,或者想暂时使用它们,那为什么还要麻烦将 key 写入磁盘呢?好的,Windows Vista说,我们可以直接将私钥加载到加密 key 对象中,然后告诉您指针。
    PKCS12_NO_PERSIST_KEY/ X509KeyStorageFlags.EphemeralKeySet
    我想认为,如果Windows在NT4中具有此功能,则它将成为.NET的默认设置。它现在不能成为默认值,因为太多的事情取决于“正常”导入如何检测私钥是否可用的内部原理。

    那最后两个呢?

    PFXImportCertStore的默认模式是私钥不应重新导出。要告诉它是错误的,可以指定 CRYPT_EXPORTABLE/ X509KeyStorageFlags.Exportable

    CAPI和CNG都支持一种机制,在使用这种机制之前,软件 key 可能需要征得同意或使用密码才能使用私钥(例如智能卡的PIN提示),但是您必须在首次创建(或导入) key 时声明这一点。 。因此,PFXImportCertStore允许您指定 CRYPT_USER_PROTECTED(.NET将其公开为 X509KeyStorageFlags.UserProtected)。

    最后两个实际上仅对“一个私钥” PFX有意义,因为它们适用于所有 key 。它们也没有包含原始键可能具有的所有选项... CNG和CAPI都支持“可存档”键,这意味着“可一次导出”。机器 key 上的自定义ACL在PFX中也不受任何支持。

    概括

    对于证书(或证书集合),一切都很容易。一旦涉及私钥,事情就会变得一团糟,并且Windows证书(存储)上的抽象会变得稀疏,您需要注意持久性模型和存储模型。

    关于.net - 所有不同的X509KeyStorageFlags的基本原理是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52750160/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com