从零开始了解 TLS 1.3 系列笔记(二)—— 实用密码学之「引言」

前言

SSL/TLS 本质上是一种密码学实践, 其目标如其名 “传输层安全”:

  • 确保真实数据不会被中间人获取: 需要数据加解密机制;
  • 确保数据不被中间人篡改: 需要消息完整性校验机制;
  • 确定对端的真实身份, 防止中间人攻击: 需要(基于证书的)身份识别机制.

为了达到上述目标, SSL/TLS 协议使用了密码学中大量的算法原语与组件, 如哈希函数, 对称加密算法, 非对称加密算法, 数字签名算法等. 在系统地理解 SSL/TLS 协议之前, 我们需要先了解这些密码学基础概念.

现代密码学概览

密码学已经从第一代广泛应用的密码学算法 (如已经退役的 MD5 跟 DES), 发展到现代密码学算法 (如 SHA-3, Argon2 以及 ChaCha20).

以下密码学基础概念(术语)将在本文以及后续文章中频繁出现, 需要熟悉:

  • 哈希函数 (Hash Function, 也称散列函数), 如 MD5, SHA-2 (包括 SHA-256, SHA-512 等), SHA-3, RIPEMD 等.
  • HMAC (Hash-based Message Authentication Code, 哈希消息认证码), 如 HMAC-SHA-256.
  • KDF (Key Derivation Function, 密钥派生函数), 如 Scrypt.
  • 密钥交换算法 (Key Exchange Algorithm), 如 Diffie-Hellman (DH), ECDH (椭圆曲线 Diffie-Hellman).
  • 对称密钥加密方案 (Symmetric key encryption schemes), 如 AES-128-GCM.
  • 使用公私钥的非对称密钥加密方案 (Asymmetric key encryption schemes), 如 RSA 和 ECC (elliptic curves-based cryptography, 椭圆曲线密码学), secp256k1 曲线跟 Ed25519 密码系统.
  • 数字签名算法 (Digital Signature Algorithm, DSA), 非对称加密和哈希算法配合使用.
  • 熵 (entropy) 与安全随机数生成器.
  • 量子安全密码学

如果你有过一些开发经验, 可能会很熟悉其中部分名词. 如果不熟也没任何关系. 本系列文章会按上面给出的顺序, 依次介绍这些密码学原语、算法或组件, 以及如何在日常开发中使用它们.

什么是密码学

密码学 (Cryptography) 是提供信息安全和保护的科学. 它在我们的数字世界中无处不在, 当你打开网站时、发送电子邮件时、连接到 WiFi 网络时, 使用账号密码登录 APP 时、使用二步认证验证码认证身份时, 都有涉及到密码学相关技术. 因此, 开发人员应该对密码学有基本的了解, 以避免写出不安全的代码. 至少也得知道如何使用密码算法和密码库, 了解哈希、对称密码算法、非对称密码算法与加密方案这些概念, 知晓数字签名及其背后的密码系统和算法.

密码学的用途

加解密

密码学的一大用途, 就是进行数据的安全存储和安全传输. 这可能涉及使用对称或非对称加密方案加密和解密数据, 其中一个或多个密钥用于将数据从明文转换为加密形式(或者相反). 按密钥数量, 可将加密算法分为两类: 对称加密和非对称加密.

  • 对称 (Symmetric) 加密, 如 AES、Twofish 和 ChaCha20, 指加密和解密消息都使用一个相同的密钥.

  • 非对称 (Asymmetric) 加密, 则使用公钥密码系统 (如 RSA 和 ECC) 和密钥对 (Key Pair) 来进行这两项操作.

    密钥对的概念比较形象, 两个密钥凑成一对, 其中一把密钥加密, 另一把解密.

一般而言, 对称加密比非对称加密更快, 但非对称加密更安全. TLS 等现代加密协议通常会结合使用对称和非对称加密, 以平衡最佳的安全性和性能.

单纯使用加密算法是不够的, 这是因为有的加密算法只能按块进行加密, 而且很多加密算法并不能保证密文的真实性、完整性. 因此, 现实中我们通常会使用加密方案进行数据的加解密. 加密方案由一系列加密算法、消息认证算法或数字签名算法、块密码模式等多种密码学原语组合得到, 以同时保证数据的安全性、真实性、完整性. 加密方案的名称就是使用到的各种密码算法名称的组合, 如 AES-256-CTR-HMAC-SHA-256、ChaCha20-Poly1305 或 ECIES-secp256k1-AES-128-GCM. 后面我们会学到.

数字签名与消息认证

密码学当中, 数字签名算法 (Digital Signature Algorithm, DSA) 算法和消息认证 (Message Authentication) 算法提供了对消息真实性 (authenticity)、完整性 (integrity) 和不可否认性 (non-repudiation) 的保证.

DSA 首先是个公钥密码学体系, 大多数数字签名算法使用非对称加密原语: 使用私钥加密特定信息, 此即签名; 由相应的公钥解密, 此即验签 (保证双方持有相同的密钥对).

MAC 跟数字签名的功能实际上是一致的, 区别在于其使用哈希算法 (如 HMAC (Hash-based Message Authentication Code, 哈希消息认证码), 或者对称加密原语.

现代加密协议通常会结合使用数字签名和消息认证.

安全随机数

密码学的另一个部分, 是熵 (entropy, 指不可预测的随机性) 和随机数的安全生成 (不可预测).

密钥交换

密码学定义了密钥交换算法 (如 Diffie-Hellman 密钥交换和 ECDH) 和密钥构建方案, 用于在需要安全传输消息的两方之间安全地构建加密密钥. 这种算法通常在两方之间建立新的安全连接时执行.

加密哈希与密码哈希

密码学提供了加密哈希函数 (如 SHA-2, SHA-3 和 BLAKE2 等) 将消息不可逆地转换为消息摘要 (Digest) / 数字指纹 (固定长度的 Hash), 并且几乎不可能找到具有相同哈希值的两条不同消息. 开发者所熟知的 MD5 和 SHA-1 已经被证明不再安全, 正是因为研究者能够构造出具有相同哈希值的两条不同消息.

而 KDF (Key Derivation Function, 密钥派生函数), 则起从文本密码安全地派生出一个哈希值 (密钥) 的作用, 并且这种算法还通过注入随机参数 (盐, salt) 和使用大量迭代和计算资源使密码破解速度变慢. 密码学提供密钥的生成手段. 毕竟人类只擅长记忆字符形式的密码, 但是各种加密算法需要的密钥都是一个非常大的、保密的数字.

混淆与扩散

在密码学当中, 香农提出的混淆 (confusion) 与扩散 (diffusion) 是设计安全密码学算法的两个原则.

混淆使密文和对称加密中密钥的映射关系变得尽可能的复杂, 使之难以分析. 如果使用了混淆, 那么输出密文中的每个比特位都应该依赖于密钥和输入数据的多个部分, 确保两者无法建立直接映射. 混淆常用的方法是「替换」与「排列」.

「扩散」将明文的统计结构扩散到大量密文中, 隐藏明文与密文之间的统计学关系. 使单个明文或密钥位的影响尽可能扩大到更多的密文中去, 确保改变输入中的任意一位都应该导致输出中大约一半的位发生变化, 反过来改变输出密文的任一位, 明文中大约一半的位也必须发生变化. 扩散常用的方法是「置换」.

这两个原则被包含在大多数哈希函数、MAC 算法、随机数生成器、对称和非对称密码算法中.

程序员经常会自嘲日常 CV, 但是在编写涉及到密码学的代码时, 一定要谨慎处理!盲目地从 Internet 复制/粘贴代码或遵循博客中的示例可能会导致安全问题; 曾经安全的代码、算法或者最佳实践, 随着时间的推移也可能变得不再安全.