我目前正在考虑开源我的一个项目,并正准备将源代码和项目结构发布给公众。现在我有一个问题:我应该如何处理我的程序集的签名密钥?我应该为开源版本创建一个新的密钥,并将其与其他文件一起发布到SVN存储库中吗?还是应该留下密钥,让每个想要编译代码的人生成自己的密钥?
您是如何处理这个问题的?我感到公开一个签名密钥有点不安。
我目前正在考虑开源我的一个项目,并正准备将源代码和项目结构发布给公众。现在我有一个问题:我应该如何处理我的程序集的签名密钥?我应该为开源版本创建一个新的密钥,并将其与其他文件一起发布到SVN存储库中吗?还是应该留下密钥,让每个想要编译代码的人生成自己的密钥?
您是如何处理这个问题的?我感到公开一个签名密钥有点不安。
对于Protocol Buffers,我释放了密钥。是的,这意味着人们实际上不能相信它是原始二进制文件 - 但对于想要修改代码并重新构建它,并仍然能够从另一个已签名程序集中使用它的任何人来说,这使他们的生活变得更加轻松。
如果有人真的想要一个可以放心信赖的Protocol Buffers版本,确保它是使用GitHub中的代码构建的正版,他们可以轻松地从他们信任的源代码自行构建。
不过我肯定可以理解两面性。我认为,如果我正在编写一个围绕安全展开的开源项目,那就可能是另一回事了。
不要发布密钥。
将签名密钥公开发布会让你感到不安。 这不是项目的签名,而是你的签名。 只有保密密钥才能维护二进制文件上签名的完整性。 公开发布密钥会破坏有关组件签名和强名称的意义和目的,从而引入新的错误可能性,并因此使每个系统 less reliable。 不要发布密钥。
对于DotNetZip,我不会发布密钥。 但是这里有一个关键点:这个密钥不属于项目;它是我的密钥。 许多人要求密钥以便重新构建已签名的二进制文件,但这毫无意义。 我使用密钥来签署比DotNetZip更多的代码。 使用我的密钥签名的任何二进制文件都是由我签名的。 使用相同的密钥生成具有相同强名称的任何两个二进制文件都保证是相同的。 发布密钥会消除这些保证,破坏强名称的整个目的以及与其相关的安全性。
想象一下开发人员选择自己的版本号,并使用我的密钥重新签名修改后的二进制文件。 现在,世界上有两个具有相同强名称但内容不同的组件。
想象一下如果我能够使用你的密钥签署任何组件。 如果你发布了密钥,我可以添加任何代码 - 即使是恶意代码 - 然后签名并偷偷地用“坏”的组件替换任何“好”的已签名二进制文件。 没有人能够区别它们之间的区别。
这是错误的。 自由共享密钥消除了使用签名组件的任何优势。
如果人们想修改项目中的代码,然后将修改版本重新用强命名组件重用,他们可以使用自己的密钥对修改的版本进行签名。 这并不困难。
我不会公开发布密钥。签名程序集的整个目的在于人们可以相信只有你接触了二进制文件,因此如果添加了任何非法代码,则签名将失效,人们知道不要信任该程序集。
签名程序集可保护你免受其他人添加“坏”代码并将其假冒为合法版本的影响。
InternalsVisibleTo
的情况下需要完整的公钥)。如果要为全新的程序集签名以获得特定的公钥标记(当然还需要公钥),则需要访问原始密钥。但是,可以直接修改原始程序集的IL(或使用诸如Fody之类的IL编织器或dnSpy工具),.Net将会愉快地加载它。因此,我认为保持私有性并没有太多价值,而且我发现许多流行的开源项目,例如GitHub for Visual Studio或Log 4 Net实际上是公开的。
另外请注意,Microsoft建议在开源项目中检查.snk文件:
如果您是开源开发人员,并且希望使用强名称程序集获得更好的.NET Framework兼容性的身份验证功能,请考虑将与程序集关联的私钥检入到您的源代码控制系统中。
他们还澄清道:
警告
不要依赖强名称进行安全性。它们仅提供唯一的标识。