有没有办法根据源代码验证二进制文件?

信息安全 源代码 正直 二进制代码
2021-08-31 13:08:01

似乎没有实用的方法来验证预编译和打包软件的完整完整性路径?我可以通过哈希检查下载的包本身,但我无法验证编译的二进制文件是否真的代表公共源代码?

这个问题甚至没有理论上的解决方案吗?在最好的情况下,一种可以自动化的方式?

也许反编译它并将它的输出或哈希与软件提供商提供的东西进行比较?

2个回答

编译主要是一种单向操作,它不是确定性的,至少不是一种健壮的方式。

可以重新编译源代码并查看它是否产生相同的二进制文件。但是,确切的二进制文件可能会因许多参数而异,包括编译选项和使用的编译器的确切版本。此外,一些编译器在二进制文件中嵌入了一些“注释”,这些注释通常包括编译器版本,但也可能包括“构建号”(如果维护了这样的数字)以及可能的构建日期和时间——在在这种情况下,您将不会得到相同的二进制文件,而不是最后一个字节。如果你想看看你是否得到了“相同”的二进制文件,你可能必须首先去掉这些注释(Unixstrip命令可能有用)。

严格来说,编译可以是随机的;由于生成最优代码是一个难题,一些编译器采用随机算法,从启发式上看,这些算法平均而言是好的。这样的编译器每次都可以生成不同的二进制文件。由于这种行为使调试变得更加困难,许多沉迷于启发式算法的编译器仍将尝试可重现(即,它们将从具有特定可配置值的PRNG中获得随机性)。


有一个更简单的解决方案:如果您有源代码并且可以重新编译它,那么只需使用重新编译的输出即可。

当然,这并不能完全解决信任问题;它只是移动它。从源代码编译时:

  • 您必须相信源代码不包含后门;
  • 你必须相信编译器本身不会对你玩讨厌的把戏。

至少,源代码名义上是人类可读的(这就是源代码的重点),因此您可以通过阅读(或让您信任的专家阅读)对代码进行一些分析。没有已知的方法可以确保给定的代码不包含任何后门或漏洞(否则,这意味着我们知道如何生成无错误的代码);然而,在源代码中隐藏后门要比在编译后的二进制文件中要难得多。

至于编译器,看这篇很经典的文章

可重现构建的概念似乎为这个问题提供了解决方案。至少是理论上的。

这意味着构建(或编译)过程的每次运行都应该返回相同的输出,因为输入源是相同的。

有了它,我或其他人可以交叉检查每个新发布的二进制文件,如果它真的代表它声称代表的源代码。

然而,只有少数项目(2017 年 2 月)已经在他们的构建过程中实现了这个概念(主要是操作系统)。所以在大多数情况下,这个解决方案仍然是一个理论上的解决方案。