#  数据安全基础

数据安全基础设施是数据加密，讯息摘要和签名工具的集合。它们提供了一种安全的方式来保护数据，以防止数据被篡改或泄露。数据安全基础设施的目标是确保数据的完整性和机密性。

| 软件包             | 命令               | 说明                                |
|-----------------|------------------|-----------------------------------|
| gnupg           | gpg(1)           | GNU 隐私卫士 - OpenPGP 加密和签名工具        |
| gpgv            | gpgv(1)          | GNU 隐私卫士 - 签名验证工具                 |
| paperkey        | paperkey(1)      | 从 OpenPGP 私钥里面，仅仅导出私密信息           |
| cryptsetup      | cryptsetup(8), … | dm-crypt 块设备加密支持 LUKS 工具          |
| coreutils       | md5sum(1)        | 计算与校验 MD5 讯息摘要                    |
| coreutils       | sha1sum(1)       | 计算与校验 SHA1 讯息摘要                   |
| openssl         | openssl(1ssl)    | 使用 "openssl dgst" (OpenSSL)计算信息摘要 |
| libsecret-tools | secret-tool(1)   | 存储和取回密码 (CLI)                     |
| seahorse        | seahorse(1)      | 密钥管理工具(GNOME)                     |

参见  “数据加密提示” 的 dm-crypt 和 fscrypt，它们通过 Linux 内核模块实现了自动数据加密架构

## GnuPG

GnuPG 是一个开放源代码的加密工具，它可以用来加密和签名文件，以及对其进行验证。它支持对称加密和非对称加密。对称加密使用同一个密钥来加密和解密数据。非对称加密使用一对密钥，一个用于加密，另一个用于解密。非对称加密的安全性取决于密钥对的生成方式。GnuPG 支持多种密钥对生成方式，包括 RSA、DSA 和 ElGamal。GnuPG 也支持 OpenPGP 的标准，因此可以与其他 OpenPGP 实现进行交互。

GnuPG 的主要命令是 gpg(1)。它可以用来生成密钥对、加密和解密文件、签名和验证签名。GnuPG 还提供了一个 gpgv(1) 命令，用来验证签名。

| 命令                          | 说明                         |
|-----------------------------|----------------------------|
| gpg --gen-key               | 生成一副新的密钥对                  |
| gpg --gen-revoke my_user_ID | 生成 my_user_ID 的一份吊销证书      |
| gpg --edit-key user_ID      | 交互式的编辑密钥，输入 "help" 来获得帮助信息 |
| gpg -o file --export        | 把所有的密钥输出到文件                |
| gpg --import file           | 从文件导入密钥                    |
| gpg --send-keys user_ID     | 发送 user_ID 的公钥到公钥服务器       |
| gpg --recv-keys user_ID     | 从公钥服务器下载 user_ID 的公钥       |
| gpg --list-keys user_ID     | 列出 user_ID 的所有密钥           |
| gpg --list-sigs user_ID     | 列出 user_ID 的签字             |
| gpg --check-sigs user_ID    | 检查 user_ID 密钥签字            |
| gpg --fingerprint user_ID   | 检查 user_ID 的指纹             |
| gpg --refresh-keys          | 更新本地密钥                     |

信任码含义

| 代码 | 信任描述           |
|----|----------------|
| -  | 没有所有者信任签名/没有计算 |
| e  | 信任计算失败         |
| q  | 没有足够的信息用于计算    |
| n  | 从不信任这个键        |
| m  | 最低限度的信任        |
| f  | 完全信任           |
| u  | 最终信任           |

如下命令上传我的 "xxxxxx" 公钥到主流的公钥服务器 "hkp://keys.gnupg.net"。

```Shell
gpg --keyserver hkp://keys.gnupg.net --send-keys xxxxxx
```

默认良好的公钥服务器在 "~/.gnupg/gpg.conf" （旧的位置在 "~/.gnupg/options"）文件中设置，此文件包含了以下信息。

```Shell
keyserver hkp://keys.gnupg.net
```

从密钥服务器获取无名密钥。

```Shell
gpg --list-sigs --with-colons | grep '^sig.*\[User ID not found\]' |\
  cut -d ':' -f 5| sort | uniq | xargs gpg --recv-keys
```

有一个错误在 OpenPGP 公钥服务器 (先前的版本 0.9.6)，会将键中断为 2 个以上的子键。新的 gnupg (>1.2.1-2) 软件包能够处理这些中断的子键。参见 gpg(1) 下的 "--repair-pks-subkey-bug" 选项.

## 在文件上使用 GnuPG

| 命令                                                    | 说明                                        |
|-------------------------------------------------------|-------------------------------------------|
| gpg -a -s file                                        | ASCII 封装的签名文件 file.asc                    |
| gpg --armor --sign file                               | 同上                                        |
| gpg --clearsign file                                  | 生成明文签字信息                                  |
| gpg --clearsign file|mail foo@example.org             | 发送一份明文签字到 foo@example.org                 |
| gpg --clearsign --not-dash-escaped patchfile          | 明文签名的补丁文件                                 |
| gpg --verify file                                     | 验证明文文件                                    |
| gpg -o file.sig -b file                               | 生成一份分离的签字                                 |
| gpg -o file.sig --detach-sig file                     | 同上                                        |
| gpg --verify file.sig file                            | 使用 file.sig 验证文件                          |
| gpg -o crypt_file.gpg -r name -e file                 | 公钥加密，从文件里面获取名字，生成二进制的 crypt_file.gpg      |
| gpg -o crypt_file.gpg --recipient name --encrypt file | 同上                                        |
| gpg -o crypt_file.asc -a -r name -e file              | 公钥加密，从文件中获取名字，生成 ASCII 封装的 crypt_file.asc |
| gpg -o crypt_file.gpg -c file                         | 将文件对称加密到 crypt_file.gpg                   |
| gpg -o crypt_file.gpg --symmetric file                | 同上                                        |
| gpg -o crypt_file.asc -a -c file                      | 对称加密，从文件到 ASCII 封装的 crypt_file.asc        |
| gpg -o file -d crypt_file.gpg -r name                 | 解密                                        |
| gpg -o file --decrypt crypt_file.gpg                  | 同上                                        |


## 在Mutt上使用 GnuPG

增加下面内容到 "~/.muttrc"，在自动启动时，避免一个慢的 GnuPG，在索引菜单中按 "S" 来允许它使用。

```Shell
macro index S ":toggle pgp_verify_sig\n"
set pgp_verify_sig=no
```

## 在 Vim 中使用 GnuPG

gnupg 插件可以让你对扩展名为 ".gpg", ".asc", 和 ".ppg"的文件可靠的运行 GnuPG。[6]

```Shell
sudo aptitude install vim-scripts
echo "packadd! gnupg" >> ~/.vim/vimrc
```

## MD5 校验和

md5sum(1) 提供了制作摘要文件的一个工具,它使用 rfc1321 里的方式制作摘要文件.

```Shell
md5sum foo bar >baz.md5
cat baz.md5
d3b07384d113edec49eaa6238ad5ff00  foo
c157a79031e1c40f85931829bc5fc552  bar

md5sum -c baz.md5
foo: OK
bar: OK
```

::: tip
MD5 校验和的 CPU 计算强度是比 GNU Privacy Guard (GnuPG) 加密签名要少的.在通常情况下,只有顶级的摘要文件才需要加密签名来确保数据完整性.
:::

## 密码密钥环

在 deepin 系统，提供了GUI（图形用户界面）工具 seahorse(1) （由GNOME开发）管理密码，安全的在密钥环 ~/.local/share/keyrings/* 里面保存它们。

`secret-tool`(1) 能够从命令行存储密码到钥匙环。

让我们存储 `LUKS/dm-crypt` 加密磁盘镜像用到的密码

```Shell
secret-tool store --label='LUKS passphrase for disk.img' LUKS my_disk.img
Password: ********
```

这个存储的密码能够被获取并给到其它程序，比如 cryptsetup(8)。

```Shell
secret-tool lookup LUKS my_disk.img | \
  cryptsetup open disk.img disk_img --type luks --keyring -
sudo mount /dev/mapper/disk_img /mnt
```

::: tip
无论何时，你需要在一个脚本里面提供密码时，使用 secret-tool 来避免将密码直接硬编码到脚本里面
:::
