延迟为程序集签名

组织可以有一个严密保护的密钥对,开发人员不能每天访问。 公钥通常可用,但对私钥的访问仅限于少数个人。 使用强名称开发程序集时,引用强名称目标程序集的每个程序集都包含用于为目标程序集指定强名称的公钥的标记。 这要求在开发过程中提供公钥。

可以在构建时使用延迟或部分签名来为可移植可执行文件(PE)中的强名称签名保留空间,但将实际签名推迟到稍后的阶段,通常在交付程序集之前。

延迟为程序集签名:

  1. 从将执行最终签名的组织处获取密钥对的公钥部分。 通常,此密钥采用 .snk 文件的形式,可以使用 Windows SDK 提供的 强名称工具(Sn.exe) 创建。

  2. 使用 System.Reflection 中的两个自定义属性为程序集的源代码进行标注。

    例如:

    [assembly:AssemblyKeyFileAttribute("myKey.snk")];
    [assembly:AssemblyDelaySignAttribute(true)];
    
    [assembly:AssemblyKeyFileAttribute("myKey.snk")]
    [assembly:AssemblyDelaySignAttribute(true)]
    
    <Assembly:AssemblyKeyFileAttribute("myKey.snk")>
    <Assembly:AssemblyDelaySignAttribute(True)>
    
  3. 编译器将公钥插入程序集清单,并为完整的强名称签名保留 PE 文件中的空间。 生成程序集时必须存储真正的公钥,以便引用此程序集的其他程序集可以获取密钥以存储在其自己的程序集引用中。

  4. 程序集没有有效的强名称签名,因此必须关闭对此签名的验证。 可以通过将 -Vr 选项与强名称工具结合使用来实现此操作。

    以下示例关闭名为 myAssembly.dll的程序集的验证。

    sn -Vr myAssembly.dll
    

    若要在无法运行强名称工具的平台(如 ARM 微处理器)上关闭验证,请使用 -Vk 选项创建注册表文件。 将注册表文件导入到要关闭验证的计算机上的注册表中。 以下示例创建一个myAssembly.dll注册表文件。

    sn -Vk myRegFile.reg myAssembly.dll
    

    使用 -Vr-Vk 选项,可以选择包含用于测试密钥签名的 .snk 文件。

    警告

    不要依赖于通过强名称实现安全性。 它们仅提供唯一标识。

    注释

    如果在 64 位电脑上使用 Visual Studio 进行开发时使用延迟签名,并且编译“任何 CPU”的程序集,可能需要两次应用 -Vr 选项。 (在 Visual Studio 中, 任何 CPU 都是 平台目标 生成属性的值;从命令行编译时,它是默认值。若要从命令行或文件资源管理器运行应用程序,请使用 Sn.exe(强名称工具) 的 64 位版本将 -Vr 选项应用于程序集。 若要在设计时将程序集加载到 Visual Studio(例如,如果程序集包含应用程序中其他程序集使用的组件),请使用强名称工具的 32 位版本。 这是因为当程序集从命令行运行时,实时 (JIT) 编译器将程序集编译为 64 位本机代码,当程序集加载到设计时环境时,将程序集编译为 32 位本机代码。

  5. 稍后,通常就在寄送之前,将程序集提交给组织的签名授权机构,以便使用强名称工具的 -R 选项进行实际的强名称签名。

    下面的示例使用 sgKey.snk 密钥对为程序集 myAssembly.dll 签署了强名称

    sn -R myAssembly.dll sgKey.snk
    

另请参阅