# 如何识别文件的真假？

- 作者：爱范儿
- 发布时间：2019-11-28 10:53
- 分类：公司
- 原文：https://www.ifanr.com/1286036

![](https://s3.ifanr.com/wp-content/uploads/2019/11/86.png)[本文](https://mp.weixin.qq.com/s?__biz=MzI4NjAxNjY4Nw==&mid=2650222335&idx=1&sn=7e52669dc8a8b063901dc9e6d94e3d05&chksm=f3e0db3fc497522952ce7f41b1695ee872d1de8e9873c1b10ca867bc2aff1a931440b8213288&mpshare=1&scene=1&srcid=&sharer_sharetime=1574761132210&sharer_shareid=bed4b55b0250f72ac3ed1c850cc3beed&rd2werd=1#wechat_redirect)来自公众号阮一峰的网络日志（ID：ruanyf-blog），作者阮一峰，爱范儿经授权发布。



每个人都下载文件，大家有没有想过，文件可能是假的，尤其来自网盘或专门的下载站。

本文就来谈谈如何识别文件的真假。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909233.jpeg "如何识别文件的真假")### 一、XcodeGhost 事件

我们从一件真实的事件说起。

2015 年 9 月，苹果手机的一些 App 被发现\[1\]向可疑网站发送数据。进一步调查确认，可疑代码是 Xcode 打包时植入的。也就是说，开发者的编程工具 Xcode 被动过手脚了。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909235.jpeg "如何识别文件的真假")腾讯的安全团队公布调查报告\[2\]，应用商店的前 5000 名应用有 76 个被感染。360 应用商店检查后发现\[3\]，共有 1076 个 App 被感染，包括微信、网易云音乐、滴滴打车、高德地图、12306、同花顺等热门应用。苹果公司将所有被感染的版本，都从官方软件商店下架了。这个事件就称为 XcodeGhost 事件\[4\]。

国家互联网应急中心专门发出了预警通知。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909237.jpeg "如何识别文件的真假")追查下去，那些动过手脚的 Xcode 都不是从官方渠道下载的，而是来自网盘或下载站。一个网名「coderfun」的人，在各种 iOS 开发者论坛或者微博留言，引诱其他开发者下载修改过的 Xcode，版本从 Xcode 6.1 到 6.4。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909239.jpeg "如何识别文件的真假")![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909241.jpeg "如何识别文件的真假")![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909243.jpeg "如何识别文件的真假")事后，这位 coderfun 发出致歉公告，表示这只是自己的一次实验，没有恶意。但是，这个事件足以引起警惕，任何下载的文件都不一定安全，很可能被修改过或植入恶意代码。

### 二、软件的防伪措施

为了防止来源不明的软件，很多平台都有签名机制。软件发布必须由认证过的开发商，使用平台的密钥签名。如果用户安装未签名的软件，平台会弹出警告，阻止安装。下面就是 MacOS 的警告。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909245.jpeg "如何识别文件的真假")但是，不可能所有开发者都去认证，尤其是认证要收费。而且，用户对这种警告不在乎，一般都会忽略或手动关闭。所以，这种做法的效果不明显。

目前的常用做法是，软件发布时，同时给出哈希码和签名文件。前者保证没有被第三方修改，后者保证确实出自原始作者。

举例来说，Linux 的发行版 Manjaro 除了提供原始的 iso 文件，还提供另外三个文件：sha1 哈希文件、sha 256 哈希文件和 sig 签名文件。它们保证了软件的真实性。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909247.jpeg "如何识别文件的真假")### 三、哈希码验证

哈希码指的是，文件内容经过哈希函数的计算，会返回一个独一无二的字符串。哪怕原始内容只改动一个字节，哈希码也会完全不同。用户下载软件后，只要计算一下哈希码，再跟作者给出的哈希码比较一下，就会知道软件有没有被改动。

目前，常用的三种哈希函数是 MD5、SHA1 和 SHA256。其中，SHA256 最安全，SHA1 次之，MD5 垫底。一般来说，软件至少会提供其中一种哈希码。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909250.jpeg "如何识别文件的真假")下面是哈希码的验证方法。

**（1）Linux 系统**

Linux 系统直接用`md5sum`、`sha1sum`、`sha256sum`这三个命令，计算哈希码。

```
$ md5sum foo.zip$ sha1sum foo.zip$ sha256sum foo.zip
```

上面命令返回文件`foo.zip`的三种哈希码。用户再跟作者给出的哈希码比对。如果不一致，文件就是被改动了，或者没有完整下载。

有时，就像前面 Manjaro 的例子，哈希码不是写在网页上，而是作为一个单独的文本文件下载。这时可以使用`-c`参数。

```
$ md5sum -c foo.zip.md5file$ sha1sum -c foo.zip.sha1file$ sha256sum -c foo.zip.sha256file
```

上面命令会返回哈希码的比对结果，直接告诉用户是否一致。

**（2）Mac 系统**

MacOS 的验证命令需要自己安装。

```
$ brew install md5sha1sum
```

执行上面命令以后，`md5sum` 和 `sha1sum` 就可以使用了。至于 `sha256sum` 要用 `shasum -a256` 命令代替。

**（3）Windows 系统**

Windows 可以下载安装免费软件 Quick hash\[5\] 或者 Raymond’s MD5 &amp; SHA Checksum Utility\[6\]。其中，Quich hash 是跨平台的，还支持 Linux 和 MacOS。

![如何识别文件的真假](https://s3.ifanr.com/wp-content/uploads/2019/11/imported-1286036-1574909252.jpeg "如何识别文件的真假")### 四、签名验证

哈希码只能保证文件内容没有修改，但是哈希码本身也有可能仿冒，完全可能连带原始文件一起造假。

文件签名能解决这个问题。软件发布时，作者用自己的私钥，对发布的软件生成一个签名文件（Manjaro 例子的 sig 文件），用户使用作者的公钥验证签名文件。

第一步，下载公钥。

软件的官网一般都会给出作者公钥的下载方法。比如，Manjaro 就可以从 GitHub 仓库下载公钥。

```
$ wget github.com/manjaro/packages-core/raw/master/manjaro-keyring/manjaro.gpg
```

公钥也有可能放在专门的公钥服务器，这时可以使用`gpg`命令在从公钥服务器下载。

```
$ gpg --keyserver hkp://eu.pool.sks-keyservers.net --search-keys [公钥 ID]
```

上面命令会列出搜索结果，让你选择是否下载某一个公钥。`--keyserver`参数指定公钥服务器，`search-keys`参数给出搜索参数，可以是作者的名称，也可以是公钥的指纹。

`gpg`命令在 Linux 下可以直接使用，MacOS 和 Windows 需要安装 GnuPG\[7\]。

第二步，导入公钥。

下载得到公钥后，将其导入操作系统。

```
$ gpg --import [公钥文件]
```

如果有完整的公钥指纹，`gpg` 命令的 `--recv-key`参数可以直接从服务器导入公钥。

```
$ gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-key "27DE B156 44C6 B3CF 3BD7 D291 300F 846B A25B AE09"
```

第三步，验证签名。

导入公钥以后，就可以验证签名文件（后缀名为 `sig`的 文件）了。

```
# 用法一$ gpg --verify [签名文件]# 用法二$ gpg --verify [签名文件] [原始文件]
```

上面命令的两种用法，效果是一样的。但是，用法一要求原始文件与签名文件同名，且在一个目录下。比如，签名文件是`foo.iso.sig`，原始文件必须是同目录下的`foo.iso`。

签名文件一般包括完整的公钥指纹，所以也可以跳过上面的第一步和第二步，直接从公钥服务器获取公钥，验证签名。

```
$ gpg --keyserver-options auto-key-retrieve --verify [签名文件]
```

（完）

### 参考资料

\[1\]发现: https://web.archive.org/web/20150920191633/http://drops.wooyun.org/news/8864  
\[2\]调查报告: https://security.tencent.com/index.php/blog/msg/96  
\[3\]发现: https://www.anquanke.com/post/id/82436  
\[4\]XcodeGhost 事件: https://zh.wikipedia.org/wiki/XcodeGhost%E9%A3%8E%E6%B3%A2  
\[5\]Quick hash: https://www.quickhash-gui.org/  
\[6\]Raymond’s MD5 &amp; SHA Checksum Utility: https://download.cnet.com/MD5-SHA-Checksum-Utility/3000-2092\_4-10911445.html  
\[7\]GnuPG: https://gnupg.org/download/index.html
