使用 HSM 进行 HLK 签名

简介

本主题介绍了在使用第三方基于网络的硬件安全模块 (HSM) 存储扩展验证 (EV) 证书时,可能会出现的一些设置和配置问题。

背景

HLK 打包

HLKX 包文件使用开放打包约定。 该规范是 ISO 工作组的一部分,意味着 HLKX 文件与 Signtool 不兼容。

HLK 打包签名

在 HLK 对包进行签名时,签名和关系会与 HLK 数据一起放入包中。 System.IO.Packaging.PackageDigitalSignature 使用这个数据来验证包中数据的签名。

注意

目前,HLK 包签名仅支持 RSA 和 DSA 证书,具体取决于用于签名 System.Security.Cryptography.Xml.SignedXml 的 .NET 库

加密服务提供程序

加密服务提供程序 (CSP) 包含加密标准和算法的实现。 CSP 至少包含一个动态链接库 (DLL),用于在 CryptoSPI(一个系统程序接口)中实现函数。 大多数 CSP 都包含它们自己的所有函数的实现。 但是,有些 CSP 主要在 Windows 服务控制管理器所管理的基于 Windows 的服务程序中实现其函数。 有些 CSP 在硬件中实现函数,例如智能卡或安全协处理器。 如果 CSP 不实现它自己的函数,DLL 将充当传递层,促进操作系统与实际 CSP 实现之间的通信。

证书存储和注册表

证书存储中的证书都映射到执行最终签名的 CSP DLL。 这可以在下面的注册表项中看到。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider]
"Image Path"="%SystemRoot%\\system32\\dssenh.dll"
"SigInFile"=dword:00000000
"Type"=dword:0000000d

使用基于网络的 HSM 托管的证书进行 HLKX 包签名

控制器配置

若要设置 HLK 控制器以使用 HSM 证书进行签名,系统上必须存在以下各项:

  • 来自 HSM 的证书颁发机构 (CA)
  • 来自 HSM 的 CSP 文件

有关如何使用这些组件配置 HSM 客户端的说明,应由你的 HSM 提供商记录。

通过 HLK 签名

如果控制器配置正确,你应该能够从 HSM 指向证书,就像从 HLK 指向本地安装的证书一样,然后对包进行签名。

测试 HSM 配置

使用 Signtool

要了解我们是否可以签名,第一步是尝试使用 Signtool 对文件进行签名。 这样我们就可以验证签名工作流是否正常运行。 首先,我们将对 PE 文件(exe 或 dll)进行签名。 例如,使用名称签名:

signtool sign /f HighValue.cer /csp "Hardware Cryptography Module" /kHighValueContainerMyControl.exe
signtool sign /n "My Company Certificate" MyFile.exe

或者使用已安装证书的 SHA1 哈希进行签名:

signtool sign /sha1 0cf1d2f7befc7d143678f86963aef5572b710cf2 MyFile.exe

证书名称位于“使用者信息”中,SHA1 哈希位于“指纹”中。 使用哈希时,删除哈希中的所有空格和特殊字符,让格式类似于上面的示例。 你还可以使用个人信息交换 (PFX) 文件进行签名。 这很可能不是你想执行的操作,因为 PFX 文件可能包含私钥,而证书仅包含公钥。

signtool sign /f certdata.pfx MyFile.exe

可以使用 Signtool 验证签名

signtool verify /v /pa MyFile.exe

如果能够使用除 PFX 文件以外的任何内容对文件进行签名和验证,可以尝试对 HLK 包进行签名。 如果无法签名,请查看“故障排除”一节。

使用 PackageDigitalSignature

在本文档末尾的“代码示例”部分中,有一个使用 PackageDigitalSignature 进行签名的代码示例。 你在收到此文档时,应该还收到了完整的 C# 文件。 若要使用此示例,需要提供未签名包的完整路径,以及要用于签名的证书的指纹。 如果无法签名,请查看“故障排除”一节。

故障排除

最有可能的原因是,你的系统上没有安装 HSM 的证书和相关的 CSP。 下面是你可以尝试的一些操作:

  • 能否只使用 HSM 供应商支持的工具在此系统上签名?
  • HSM 供应商是否在此系统上安装了证书和 CSP?
    • 证书属性是什么?
  • HSM 供应商是否支持和记录对 Signtool 的使用? 如果可以使用 Signtool 和 HSM 对文件进行签名,表明系统已正确配置,并表示 HLK 还可以对 HLKX 包进行签名。
  • 运行示例代码 (HSM_example.cs) 时,CspKeyContainerInfo.ProviderName 的输出内容是什么
    • 该提供程序名称是否映射到供应商提供的正确的 CSP DLL。 可以在注册表中找到该信息,如上所示。

代码示例

PackageDigitalSignatureManager

public static void Sign(string package, X509Certificate2 certificate)
{
  // Open the package to sign it
  Package packageToSign = Package.Open(package);

  // Specify that the digital signature should exist 
  // embedded in the signature part
  PackageDigitalSignatureManager signatureManager = new PackageDigitalSignatureManager(packageToSign);

  signatureManager.CertificateOption = CertificateEmbeddingOption.InCertificatePart;

  // We want to sign every part in the package
  List<Uri> partsToSign = new List<Uri>();
  foreach (PackagePart part in packageToSign.GetParts())
  {
    partsToSign.Add(part.Uri);
  }

  // We will sign every relationship by type
  // This will mean the signature is invalidated if *anything* is modified in                           //the package post-signing
  List<PackageRelationshipSelector> relationshipSelectors = new List<PackageRelationshipSelector>();

  foreach (PackageRelationship relationship in packageToSign.GetRelationships())
  {
    relationshipSelectors.Add(new PackageRelationshipSelector(relationship.SourceUri, PackageRelationshipSelectorType.Type, relationship.RelationshipType));
  }

  try
  {
    signatureManager.Sign(partsToSign, certificate, relationshipSelectors);
  }
  finally
  {
    packageToSign.Close();
  }
}