密钥存储和检索

密钥存储体系结构

CNG 提供了一种私钥存储模型,允许根据当前和未来的需求来适应使用加密功能(如公钥或私钥加密)的应用程序的创建需求,以及密钥材料存储的要求。 密钥存储路由器是此模型中的中心例程,在 Ncrypt.dll中实现。 应用程序通过密钥存储路由器访问系统上的密钥存储提供程序(KSP),该路由器会隐藏应用程序和存储提供程序本身的详细信息,例如密钥隔离。 下图显示了 CNG 密钥隔离体系结构的设计和功能。

cng 密钥存储提供程序

为了符合常见标准(CC)要求,必须隔离长期密钥,以便它们永远不会出现在应用程序过程中。 CNG 当前支持通过微软软件 KSP 来存储非对称私钥,这款软件与 Windows Server 2008 和 Windows Vista 一起附带,并默认安装。

默认情况下,Windows Server 2008 和 Windows Vista 中启用了密钥隔离。 在此之前的平台上没有关键隔离功能。 此外,不会在密钥隔离服务(LSA 进程)中加载第三方 KSP。 在密钥隔离服务中,只有Microsoft KSP被加载。

LSA 进程用作密钥隔离过程,以最大程度地提高性能。 对私钥的所有访问都通过密钥存储路由器,该路由器公开了一组用于管理和使用私钥的综合功能。

CNG 将存储密钥的公共部分与专用部分分开存储。 密钥对的公共部分也保留在密钥隔离服务中,并使用本地远程过程调用 (LRPC) 进行访问。 密钥存储路由器在调用密钥隔离过程时使用 LRPC。 对私钥的所有访问都经过私钥路由器,并由 CNG 审核。

如上所述,可以支持各种硬件存储设备。 在每个情况下,所有这些存储设备的接口都是相同的。 它包括执行各种私钥操作的函数以及与密钥存储和管理相关的功能。

CNG 提供了一组用于创建、存储和检索加密密钥的 API。 有关这些 API 的列表,请参阅 CNG 密钥存储函数

钥匙种类

CNG 支持以下密钥类型:

  • Diffie-Hellman 公钥和私钥。
  • 数字签名算法(DSA、FIPS 186-2)公钥和私钥。
  • RSA (PKCS #1) 公钥和私钥。
  • 几个旧版 (CryptoAPI) 公钥和私钥。
  • 椭圆曲线加密公钥和私钥。

支持的算法

CNG 支持以下密钥算法。

算法 键/哈希长度(位)
RSA 512 到 16384,以 64 位为增量
DH 512 到 16384,以 64 位为增量
DSA 512 到 1024,以 64 位为增量
ECDSA P-256、P-384、P-521(NIST 曲线)
ECDH P-256、P-384、P-521(NIST 曲线)
MD2 128
MD4 128
MD5 128
SHA-1 160
SHA-256 256
SHA-384 384
SHA-512 512

密钥目录和文件

Microsoft旧的 CryptoAPI CSP 将私钥存储在以下目录中。

键类型 目录
用户私密 %APPDATA%\Microsoft\Crypto\RSA\User SID\
%APPDATA%\Microsoft\Crypto\DSS\User SID\
本地系统私有 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\S-1-5-18\
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\DSS\S-1-5-18\
本地服务专用 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\S-1-5-19\
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\DSS\S-1-5-19\
网络服务专用 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\S-1-5-20\
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\DSS\S-1-5-20\
共享专用 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\DSS\MachineKeys

CNG 将私钥存储在以下目录中。

键类型 Directory
用户私密 %APPDATA%\Microsoft\Crypto\Keys
本地系统私有 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\SystemKeys
本地服务专用 %WINDIR%\ServiceProfiles\LocalService
网络服务私有 %WINDIR%\ServiceProfiles\NetworkService
共享专用 %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys

以下是 CryptoAPI 和 CNG 密钥容器之间的一些差异。

  • CNG 对密钥文件使用的文件名不同于由 Rsaenh.dll 和 Dssenh.dll 旧式 CSP 创建的密钥文件的文件名。 旧密钥文件也有.key扩展名,但 CNG 密钥文件没有.key扩展名。
  • CNG 完全支持 Unicode 密钥容器名称;CNG 使用 Unicode 容器名称的哈希,而 CryptoAPI 使用 ANSI 容器名称的哈希。
  • 对于 RSA 密钥对,CNG 更灵活。 例如,CNG 支持长度大于 32 位的公共指数,并支持 p 和 q 是不同长度的键。
  • 在 CryptoAPI 中,密钥容器文件存储在一个目录中,该目录的名称是用户 SID(安全标识符)的文本等价物。 CNG 不再如此,这消除了将用户从一个域移动到另一个域而不丢失其所有私钥的难度。
  • CNG KSP 和密钥名称限制为 MAX_PATH Unicode 字符。 CryptoAPI CSP 和密钥名称限制为 MAX_PATH ANSI 字符。
  • CNG 提供用户定义的密钥属性的功能。 用户可以创建自定义属性并将其与密钥相关联,并将它们与持久密钥一起存储。

保存密钥时,CNG 可以创建两个文件。 第一个文件包含新的 CNG 格式的私钥,并且总是会被创建。 旧版 CryptoAPI CSP 无法使用此文件。 第二个文件在旧版 CryptoAPI 密钥容器中包含相同的私钥。 第二个文件符合 Rsaenh.dll所使用的格式和位置。 只有在调用 NCryptFinalizeKey 函数以完成 RSA 密钥时指定了 NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG 标志时,才会创建第二个文件。 DSA 和 DH 密钥不支持此功能。

当应用程序尝试打开现有的持久密钥时,CNG 会首先尝试打开本机 CNG 文件。 如果此文件不存在,则 CNG 会尝试在旧版 CryptoAPI 密钥容器中找到匹配的密钥。

使用 Windows 用户状态迁移工具(USMT)将 CryptoAPI 密钥从源计算机移动到目标计算机或将 CryptoAPI 密钥复制到目标计算机时,CNG 将无法访问目标计算机上的密钥。 若要访问此类迁移的密钥,必须使用 CryptoAPI。

CNG 密钥存储函数

密钥存储属性标识符

NCryptFinalizeKey