【问题标题】:What is the recommended way to manage a strong-name key pair for an open-source project?为开源项目管理强名称密钥对的推荐方法是什么?
【发布时间】:2009-12-02 07:43:08
【问题描述】:

我管理一个开源项目,并希望签署项目二进制包中发布的二进制文件。我使用 Visual Studio csprojsln 文件来管理和构建我的项目,并将这些文件作为项目源包的一部分分发。

如何签署生成的构建二进制文件而不必分发snk 密钥对文件?如果我使用 Visual Studio 对程序集进行签名,则每个项目文件现在都需要密钥对的副本才能构建。我不喜欢分发密钥对,即使它受密码保护。

编辑

另一个需要注意的是,项目中的某些程序集通过InternalsVisibleToAttribute 授予好友访问权限,并通过项目引用构建这些好友。因此,此类程序集在引用已签名程序集时需要使用强名称。但是,如果密钥对未分发,那么最终用户如何构建源代码并维护项目关系?如果使用临时密钥对文件,签名程序集的公钥令牌是否会更改,从而破坏 InternalsVisibleToAttribute 引用?

【问题讨论】:

    标签: c# visual-studio open-source assembly-signing strongname


    【解决方案1】:

    您不应分发密钥对。 strongname 用于验证新版本的程序集是否来自同一发布者。

    如果其他开发人员想要对您的项目进行分支,他们将生成自己的密钥对,这将有效地表明他们的版本不是来自您,因此除非重新编译,否则依赖于您的其他程序集将不再加载。这并不总是很方便,但它可以保护您免受有人发布恶意版本的程序集并静默分发它。

    【讨论】:

    • 由于我需要分发项目和解决方案文件,并且由于构建解决方案需要密钥对(启用签名时),我是否还应该分发“虚拟”密钥对以便最终用户无需操作项目文件即可构建?签入禁用签名的项目文件似乎很麻烦,每次发布时都必须切换此设置。
    • 您可以执行以下操作:添加一个构建步骤以检查 .snk 文件是否已存在,并在必要时运行 sn.exe 以生成新文件。然后它将直接从存储库中为其他用户构建。
    • 确保发布者身份不是强名称签名的预期目的。您应该为此使用Authenticode。微软自己的文档建议发布 SNK 文件:docs.microsoft.com/en-us/dotnet/standard/assembly/…
    【解决方案2】:

    这是一个老问题,但目前投票率最高的答案并不准确,所以我认为值得发布一个新答案。

    对于开源项目,Microsoft 建议将您的私钥签入您的存储库。这是安全的,因为强名称密钥用于标识,而不是安全。

    参考这里:https://docs.microsoft.com/en-us/dotnet/framework/app-domains/strong-named-assemblies

    不要依赖强名称来保证安全。它们仅提供唯一身份。

    他们还专门针对开源项目:

    如果您是开源开发人员,并且希望获得强名称程序集的身份优势,请考虑将与程序集关联的私钥签入您的源代码控制系统。

    如果您希望您的程序集安全,那么您应该查看 Authenticode 签名https://blogs.msdn.microsoft.com/shawnfa/2005/12/13/authenticode-and-assemblies/

    【讨论】:

      【解决方案3】:

      Sharptooth's solution 如果代码中唯一的程序集引用是项目文件中编码的那些,则效果很好。如果您的项目通过InternalsVisibleToAttribute 或其他需要强名称字符串的方式引用其他程序集,则使用临时密钥构建存储库源是不可行的。这样做会更改强名称字符串中存在的公钥引用并破坏代码。

      我的应用程序就是这种情况,所以我需要采用不同的方法。

      我基本上在单独的文件夹层次结构中创建了slncsproj 文件的副本,并按如下方式修改了csproj 文件。

      • 将所有文件引用转换为链接,指向原始来源。
      • 复制并修改了每个 AssemblyInfo.cs 文件以包含对具有强名称的 InternalsVisibleToAttribute 的使用。
      • 修改了每个csproj 文件,使snk 文件引用为相对路径(无需将snk 文件复制到每个项目中)

      我首先手动完成了所有这些操作,但后来意识到这可以通过简单的方式实现自动化。第一步和第三步可以用 XSLT 来实现,而第二步可以用正则表达式搜索/替换功能来实现。

      由于我现在需要维护两个解决方案,因此自动执行此任务以避免未来的麻烦是有意义的。

      存储库中的源不使用强名称构建程序集,这很好,因为我不想对最终用户施加任何构建限制或流程。

      【讨论】:

        猜你喜欢
        • 2019-01-26
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        • 2020-08-05
        • 1970-01-01
        • 2011-08-17
        • 1970-01-01
        • 2021-10-04
        相关资源
        最近更新 更多