Security and Cryptography(安全和密码学)


https://missing.csail.mit.edu/2020/security/
https://missing-semester-cn.github.io/2020/security/

熵(Entropy)

  (Entropy) 度量了不确定性并可以用来决定密码的强度。
  的单位是 比特。对于一个均匀分布的随机离散变量,熵等于log_2(所有可能的个数,即n)。 扔一次硬币的熵是log_2(2)=1比特。掷一次(六面)骰子的熵为log_2(6)=2.58比特。大约40比特的熵足以对抗在线穷举攻,而对于离线穷举攻击, 一般需要更强的密码 (比如80比特或更多)。

散列函数(Hash functions)

  密码散列函数 (Cryptographic hash function) 可以将任意大小的数据映射为一个固定大小的输出。除此之外,还有一些其他特性。 一个散列函数的大概规范如下:

hash(value: array<byte>) -> vector<byte, N>  (N对于该函数固定)

  SHA-1Git中使用的一种散列函数, 它可以将任意大小的输入映射为一个160比特(可被40位十六进制数表示)的输出。(虽然SHA-1还可以用于特定用途,但它已经不再被认为是一个强密码散列函数。) 下面我们用sha1sum(注意sha1sum中1是数字而非字母l)命令来测试SHA1对几个字符串的输出:

$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'Hello' | sha1sum 
f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0

  抽象地讲,散列函数可以被认为是一个不可逆,且看上去随机(但具确定性)的函数。 一个散列函数拥有以下特性:

  • 确定性(Deterministic):对于不变的输入永远有相同的输出。
  • 不可逆性(Non-invertible):对于hash(m) = h,难以通过已知的输出h来计算出原始输入m。
  • 目标碰撞抵抗性(Target collision resistant):对于一个给定输入m_1,难以找到m_2 != m_1且hash(m_1) = hash(m_2)。
  • 碰撞抵抗性(Collision resistant):难以找到一组满足hash(m_1) = hash(m_2)的输入m_1, m_2(该性质严格强于目标碰撞抵抗性)。

密码散列函数的应用

  • Git中的内容寻址存储(Content addressed storage)
  • 文件的信息摘要(Message digest):像Linux ISO这样的软件可以从非官方的(有时不太可信的)镜像站下载,所以需要设法确认下载的软件和官方一致。 官方网站一般会在(指向镜像站的)下载链接旁边备注安装文件的哈希值。 用户从镜像站下载安装文件后可以对照公布的哈希值来确定安装文件没有被篡改。
  • 承诺机制(Commitment scheme): 假设我希望承诺一个值,但之后再透露它—— 比如在没有一个可信的、双方可见的硬币的情况下在我的脑海中公平的“扔一次硬币”。 我可以选择一个值r = random(),并和你分享它的哈希值h = sha256(r)。 这时你可以开始猜硬币的正反:我们一致同意偶数r代表正面,奇数r代表反面。 你猜完了以后,我告诉你值r的内容,得出胜负。同时你可以使用sha256(r)来检查我分享的哈希值h以确认我没有作弊。

密钥生成函数(Key derivation functions)

  密钥生成函数 (Key Derivation Functions) 作为密码散列函数的相关概念,被应用于包括生成固定长度并可在其他密码算法中使用的密钥等方面。 为了对抗穷举法攻击,密钥生成函数通常较慢。

  应用:

  • 从密码生成可以在其他加密算法中使用的密钥,比如对称加密算法。
  • 存储登录凭证。Storing plaintext passwords is bad; the right approach is to generate and store a random salt salt = random() for each user, store KDF(password + salt), and verify login attempts by re-computing the KDF given the entered password and the stored salt.

对称加密

keygen() -> key  (这是一个随机方法)

encrypt(plaintext: array<byte>, key) -> array<byte>  (输出密文)
decrypt(ciphertext: array<byte>, key) -> array<byte>  (输出明文)

decrypt(encrypt(m, k), k) = m

AES 是现在常用的一种对称加密系统。

非对称加密

  非对称加密的“非对称”代表在其环境中,使用两个具有不同功能的密钥: 一个是私钥(private key),不向外公布;另一个是公钥(public key),公布公钥不像公布对称加密的共享密钥那样可能影响加密体系的安全性。
  非对称加密使用以下几个方法来实现加密/解密(encrypt/decrypt),以及签名/验证(sign/verify):

keygen() -> (public key, private key)  (这是一个随机方法)

encrypt(plaintext: array<byte>, public key) -> array<byte>  (输出密文)
decrypt(ciphertext: array<byte>, private key) -> array<byte>  (输出明文)

sign(message: array<byte>, private key) -> array<byte>  (生成签名)
verify(message: array<byte>, signature: array<byte>, public key) -> bool  (验证签名是否是由和这个公钥相关的私钥生成的)

  非对称的加密/解密方法和对称的加密/解密方法有类似的特征。
  信息在非对称加密中使用公钥加密, 且输出的密文很难在不知道私钥的情况下得出明文。
  解密方法decrypt()有明显的正确性。 给定密文及私钥,解密方法一定会输出明文: decrypt(encrypt(m, public key), private key) = m
  对称加密和非对称加密可以类比为机械锁。 对称加密就好比一个防盗门:只要是有钥匙的人都可以开门或者锁门。 非对称加密好比一个可以拿下来的挂锁。你可以把打开状态的挂锁(公钥)给任何一个人并保留唯一的钥匙(私钥)。这样他们将给你的信息装进盒子里并用这个挂锁锁上以后,只有你可以用保留的钥匙开锁。
  签名/验证方法具有和书面签名类似的特征。
  在不知道私钥的情况下,不管需要签名的信息为何,很难计算出一个可以使 verify(message, signature, public key) 返回为真的签名。
  对于使用私钥签名的信息,验证方法验证和私钥相对应的公钥时一定返回为真: verify(message, sign(message, private key), public key) = true

非对称加密的应用

  • PGP电子邮件加密:用户可以将所使用的公钥在线发布,比如:PGP密钥服务器或 Keybase。任何人都可以向他们发送加密的电子邮件。
  • 聊天加密:像 Signal 和 Keybase 使用非对称密钥来建立私密聊天。
  • 软件签名:Git 支持用户对提交(commit)和标签(tag)进行GPG签名。任何人都可以使用软件开发者公布的签名公钥验证下载的已签名软件。

密钥分发

  Asymmetric-key cryptography is wonderful, but it has a big challenge of distributing public keys / mapping public keys to real-world identities. There are many solutions to this problem. Each model has its merits(优势), we (the instructors) like Keybase’s model.

  • Signal has one simple solution: trust on first use, and support out-of-band public key exchange (you verify your friends’ “safety numbers” in person).
  • PGP has a different solution, which is web of trust.
  • Keybase has yet another solution of social proof (along with other neat ideas).

案例分析(Case studies)

密码管理器(Password managers)

  密码管理器(如KeePassXC、pass 和 1Password)会帮助你对每个网站生成随机且复杂(表现为高熵)的密码,并使用你指定的主密码配合密钥生成函数来对称加密它们。
  你只需要记住一个复杂的主密码,密码管理器就可以生成很多复杂度高且不会重复使用的密码。密码管理器通过这种方式降低密码被猜出的可能,并减少网站信息泄露后对其他网站密码的威胁。

两步验证(双因子验证)(Two-factor authentication)

  Two-factor authentication (2FA) requires you to use a passphrase (“something you know”) along with a 2FA authenticator(身份验证器) (like a YubiKey, “something you have”) in order to protect against stolen passwords and phishing attacks(钓鱼攻击).

(全盘加密)Full disk encryption

  Keeping your laptop’s entire disk encrypted is an easy way to protect your data in the case that your laptop is stolen. You can use cryptsetup + LUKS on Linux, BitLocker on Windows, or FileVault on macOS. This encrypts the entire disk with a symmetric cipher(对称密钥), with a key protected by a passphrase.

聊天加密(Private messaging)

  Use Signal or Keybase. End-to-end security is bootstrapped from asymmetric-key encryption. Obtaining your contacts’ public keys is the critical step here. If you want good security, you need to authenticate public keys out-of-band (with Signal or Keybase), or trust social proofs (with Keybase)
  SignalKeybase使用非对称加密对用户提供端到端(End-to-end)安全性。获取联系人的公钥非常关键。为了保证安全性,应使用线下方式验证Signal或者Keybase的用户公钥,或者信任Keybase用户提供的社交网络证明。

SSH

  当你运行ssh-keygen命令,它会生成一个非对称密钥对:公钥和私钥(public_key, private_key)。生成过程中使用的随机数由系统提供的熵决定。这些熵可以来源于硬件事件(hardware events)等。 公钥最终会被分发,它可以直接明文存储。 但是为了防止泄露,私钥必须加密存储。ssh-keygen命令会提示用户输入一个密码,并将它输入密钥生成函数产生一个密钥。最终,ssh-keygen使用对称加密算法和这个密钥加密私钥。
  在实际运用中,当服务器已知用户的公钥(存储在.ssh/authorized_keys文件中,一般在用户HOME目录下),尝试连接的客户端可以使用非对称签名来证明用户的身份——这便是挑战应答(challenge-response)方式。 简单来说,服务器选择一个随机数字发送给客户端。客户端使用用户私钥对这个数字信息签名后返回服务器。 服务器随后使用.ssh/authorized_keys文件中存储的用户公钥来验证返回的信息是否由所对应的私钥所签名。这种验证方式可以有效证明试图登录的用户持有所需的私钥。

Exercises

  1. 熵Entropy.
    1. Suppose a password is chosen as a concatenation of four lower-case dictionary words, where each word is selected uniformly at random from a dictionary of size 100,000. An example of such a password is correcthorsebatterystaple. How many bits of entropy does this have?

    H = log_2_(100,000^4)

    1. Consider an alternative scheme where a password is chosen as a sequence of 8 random alphanumeric characters (including both lower-case and upper-case letters). An example is rg8Ql34g. How many bits of entropy does this have?

    log_2_((26*2+10)^8)

  2. 使用 OpenSSLAES模式加密一个文件: openssl aes-256-cbc -salt -in {源文件名} -out {加密文件名}。 使用cat或者hexdump对比源文件和加密的文件,再用 openssl aes-256-cbc -d -in {加密文件名} -out {解密文件名} 命令解密刚刚加密的文件。最后使用cmp命令确认源文件和解密后的文件内容相同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小小马里奥_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值