一、简介
本文介绍了密码学的基本原理,其中实战部分讲述了如何利用非对称加密实现私密信息传输,保护好自己的隐私。
二、熵
熵的单位是比特。
对于一个均匀分布的随机离散变量,熵等于 log_2(n), n 为所有可能的个数。
扔一次硬币的熵是 1 比特, l o g 2 ( 2 ) = 1 log_2(2) = 1 log2(2)=1。
掷一次六面骰子的熵大约为 2.58 比特, l o g 2 ( 6 ) = 2.58 log_2(6) = 2.58 log2(6)=2.58。
如图,“Tr0ub4dor&3” 的熵为 log_2(28),至少需要 3 天破解。
“correcthorsebatterystaple” 的熵为 log_2(44),至少需要 550 年破解。
因此 “correcthorsebatterystaple” 这个密码比 “Tr0ub4dor&3” 更安全,而且该密码是简单的单词组合,更好记忆。
一般来说,对于受限于网络速度和应用认证机制的在线穷举攻击,大约 40 比特的熵足以对抗。
而对于受限于计算速度的离线穷举攻击, 需要更强的比如 80 比特或更多的密码。
三、散列函数
密码散列函数 (Cryptographic hash function) 可以将任意大小的数据映射为一个固定大小的输出。
SHA-1 是 Git 中使用的一种散列函数, 它可以将任意大小的输入映射为一个 160 比特(可被 40 位十六进制数表示)的输出。
下面我们用 sha1sum 命令来测试 SHA1 对几个字符串的输出:
$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'Hello' | sha1sum
f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0
下载文件时,我们也可以用 sha256 生成的输出验证下载的 iso 镜像是否完整
$ sha256sum debian-12.0.0-amd64-DVD-1.iso
85042209e89908d5b59a968ff1be3c54415fa23015bf015562bad8d22452fa80`
四、对称加密
对称加密使用以下几个方法来实现这个功能:
def keygen() -> str:
#生成密钥 key
def encrypt(plaintext: str, key: str) -> str:
#加密,输出密文
def decrypt(ciphertext: str, key:str) -> str:
#解密:输出明文
五、非对称加密
非对称加密使用两个不同功能的密钥: 一个是私钥(private key),不向外公布,用来解密;另一个是公钥(public key),开放给使用者加密。
非对称加密使用以下几个方法来实现加密/解密(encrypt/decrypt),以及签名/验证(sign/verify):
def keygen() -> tuple[str, str] :
#生成公钥和私钥
def encrypt(plaintext: str, public: str) -> str:
#公钥加密,输出密文
def decrypt(ciphertext: str, private:str) -> str:
#私钥解密:输出明文
def sign(message: str, private:str) -> str:
#私钥生成签名
def verify(message: str, signature: str, public str) -> bool
#公钥验证签名
使用私钥签名确保只有私钥的持有者才能生成有效的签名,而使用公钥验证的目的是让任何人都能够验证签名的合法性。
六、实战非对称加密
- 生成一个 2048 位长度的 RSA 私钥文件 private.pem
$ openssl genrsa -out private.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
....................+++++
.......................................................+++++
e is 65537 (0x010001)
- 从 RSA 私钥中导出公钥 public.pem:
$ openssl rsa -in private.pem -out public.pem -pubout
- 加密 txt 文件的数据,结果保存在 ciphertext:
openssl rsautl -encrypt -in plaintext.txt -out ciphertext.txt -inkey public.pem -pubin
- 解密文件/数据结果保存在 decrypted.txt 中:
openssl rsautl -decrypt -in ciphertext.txt -out decrypted.txt -inkey private.pem
我们对比 plaintext.txt 和 decrypted.txt,内容一致,加解密成功。
发送敏感文件时,我们可以向对方索取公钥,然后利用公钥加密文件再传给他,实现了加密通信。可以说只有对方才能解开,第三方难以破解。