Solution-安全与密码学
1. 熵
假设一个密码是从四个小写的单词拼接组成,每个单词都是从一个含有 10 万单词的字典中随机选择,且每个单词选中的概率相同。 一个符合这样构造的例子是 correcthorsebatterystaple
。这个密码有多少比特的熵?
假设另一个密码是用八个随机的大小写字母或数字组成。一个符合这样构造的例子是 rg8Ql34g
。这个密码又有多少比特的熵?
Entropy = log_2(100000^4) = 66 #correcthorsebatterystaple
Entropy = log_2((26+26+10)^8) = 48 #rg8Ql34g
也可以使用下面两个网址进行计算
哪一个密码更强? 假设一个攻击者每秒可以尝试 1 万个密码,这个攻击者需要多久可以分别破解上述两个密码?
第一个更强。
因为每个密码的概率是相同,所以平均而言,需要的破解时间约为尝试所有可能密码所花时间的一半(概率论期望值的简单应用,记所有可能密码个数为 x, 每年尝试的密码数为 y, 破解所需的平均时间为:$\frac{1}{x\cdot y}(1+2+\cdots +x)=\frac{1}{x}\times \frac{(1+x)\times x/2}{y}=\frac{1}{2}\times\frac{1+x}{y}$ )
对于第一个密码:$100,000^4/10^4/(365\times 24\times 3600)/2=1.085亿年$
对于第二个密码:$62^8/10^4/(365\times 24\times 3600)/2=346年$
2. 密码散列函数
从 Debian 镜像站 下载一个光盘映像(比如这个来自阿根廷镜像站的 映像)。使用 sha256sum
命令对比下载映像的哈希值和官方 Debian 站公布的哈希值。如果你下载了上面的映像,官方公布的哈希值可以 参考这个文件。
curl -O -L -C - http://debian.xfree.com.ar/debian-cd/current/amd64/iso-cd/debian-mac-10.9.0-amd64-netinst.iso
curl -O https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS
注意这里 SHA256SUMS 包含的版本号,下载的 iso 文件也要是对应的版本号。原文中是 10.2.0 版本,这里我们下载的是 10.9.0。当您看到此文时,可能版本又更新了,请到 这里 下载最新版本。
接下来进行哈希比对:
cat SHA256SUMS | grep debian-10.9.0-amd64-netinst.iso
8660593d10de0ce7577c9de4dab886ff540bc9843659c8879d8eea0ab224c109 debian-10.9.0-amd64-netinst.iso
shasum -a 256 debian-10.9.0-amd64-netinst.iso
8660593d10de0ce7577c9de4dab886ff540bc9843659c8879d8eea0ab224c109 debian-10.9.0-amd64-netinst.iso
可以看出来两个哈希是一样的。
也可以用 diff
直接比较:
diff <(cat SHA256SUMS |grep debian-10.9.0-amd64-netinst.iso) <(shasum -a 256 debian-10.9.0-amd64-netinst.iso)
3. 对称加密
使用 OpenSSL 的 AES 模式加密一个文件: openssl aes-256-cbc -salt -in {源文件名} -out {加密文件名}
。 使用 cat
或者 hexdump
对比源文件和加密的文件,再用 openssl aes-256-cbc -d -in {加密文件名} -out {解密文件名}
命令解密刚刚加密的文件。最后使用 cmp
命令确认源文件和解密后的文件内容相同。
echo "hello world" > afile # 创建一个文件
openssl aes-256-cbc -salt -in afile -out secfile # 加密文件
enter aes-256-cbc encryption password:***
Verifying - enter aes-256-cbc encryption password:***
使用 hexdump
比较两个文件
diff <(hexdump afile) <(hexdump secfile)
1,2c1,3
< 0000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a
< 000000c
---
> 0000000 53 61 6c 74 65 64 5f 5f cb 18 f1 7c 4f 09 b4 21
> 0000010 d2 f1 56 77 80 01 b1 2f ac 2d 32 35 52 23 2e c6
> 0000020
使用 cat
比较两个文件
cat afile
# hello world
cat secfile
# Salted__|O !Vw/-25R#.%
对文件进行解密
openssl aes-256-cbc -d -in secfile -out notsafefile
cmp afile notsafefile
$?
# 返回0,表示这两个文件内容相同
4. 非对称加密
- 在你自己的电脑上使用更安全的 ED25519 算法生成一组 SSH 密钥对。为了确保私钥不使用时的安全,一定使用密码加密你的私钥。
ssh-keygen -t ed25519
- 配置 GPG。
Linux 系统可以直接按照上面的教程操作,MacOS 上的操作过程如下
$ brew install gpg $ gpg --gen-key
-
给 Anish 发送一封加密的电子邮件(Anish 的公钥)。
导入 Anish 发布的公钥,并完成验证
~ $ curl https://keybase.io/anish/pgp_keys.asc | gpg --import ~ $ gpg --list-keys # ~/.gnupg/pubring.kbx中除了刚才创建的自己的公钥,还存入了Anish的公钥 ~ $ gpg --edit-key "Anish Athalye" # 进入gpg控制台 gpg> fpr pub rsa4096/C3F6E4F5086B3B32 2014-10-30 Anish Athalye <me@anishathalye.com> 主密钥指纹: 72EE 4824 FA6E FF1F E750 A015 C3F6 E4F5 086B 3B32 # 将这个密钥指纹与Anish发布在网站上的做匹配,一致
接下来,使用 Anish 的公钥加密信息
~ $ touch message.txt ~ $ echo 'hello' > message.txt ~ $ gpg --encrypt --sign --armor -r me@anishathalye.com message.txt # 在本目录下会生成一个message.txt.asc的加密文件 # 这个文件,只有拥有私钥的Anish能解密 # 如果你也想查看这个加密文件,需要使用: ~ $ gpg --encrypt --sign --armor -r me@anishathalye.com -r usrname@example.com message.txt # 添加第二个 -r 接收人为你自己,你就能解密这个文件 ~ $ gpg message.txt.asc
接下来,你就可以尝试用邮件或其他方式,将这个使用 Anish 的公钥加密的文件发送给他(这里只是做说明,不推荐发送无意义的信息!)
- 使用
git commit -S
命令签名一个 Git 提交,并使用git show --show-signature
命令验证这个提交的签名。或者,使用 git tag -s 命令签名一个 Git 标签,并使用git tag -v
命令验证标签的签名。git commit -S -m "sign a commit"
可能会出现下面的错误
error: gpg failed to sign the data fatal: failed to write commit object
这个问题网上有一些解决方案可供参考:
如果遇到
echo "test" | gpg --clearsign gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device
则执行
export GPG_TTY=$(tty)
此外要注意
~/.gitconfig
里面的 name,email 要和生成秘钥时使用的一样,签名算法也是一样的:gpg -K --keyid-format SHORT /Users/lingfeng/.gnupg/pubring.kbx ---------------------------------- sec rsa2048/56EF5DE3 2021-05-15 [SC] [有效至:2023-05-15] 35A0BAB790EBBFE193422975097FC49956EF5DE3 uid [ 绝对 ] hanxiaomax-mac <hanxiaomax@qq.com> ssb rsa2048/55FB9195 2021-05-15 [E] [有效至:2023-05-15]
对应的
.gitconfig
为[user] name = hanxiaomax-mac email = hanxiaomax@qq.com signingKey = 55FB9195
所有问题都解决后,正常签名
git commit -S -m "sign a commit" [main fc8e916] sign a commit 3 files changed, 3 insertions(+) create mode 100644 security/afile create mode 100644 security/notsafefile create mode 100644 security/secfile
创建一个带签名的标签,并验证
~/signgit (main) $ git tag -s "v0.0.0" -m "Create a tag" ~/signgit (main) $ git tag -v v0.0.0 object 03fa307f9ced5d9717473a429d76122e46c7a70f type commit tag v0.0.0 tagger usrname <usrname@example.com> 1683883065 +0800 Create a tag gpg: Signature made Fri May 12 17:18:13 2023 CST gpg: using RSA key 07C700F1B0F8A6BFDA61571CA29FF423FCBD1279 gpg: issuer "usrname@example.com" gpg: Good signature from "usrname <usrname@example.com>" [ultimate]
Licensed under CC BY-NC-SA.