【ZeroRange WebRTC】码学基础与实践:哈希、HMAC、AES、RSA/ECDSA、随机数、X.509

密码学基础与实践:哈希、HMAC、AES、RSA/ECDSA、随机数、X.509

面向工程实践的系统指南:从原理到落地。涵盖 SHA 系列哈希、HMAC、对称加密(AES 及模式)、非对称(RSA/ECDSA/Ed25519)、安全随机数与熵源、X.509 证书的生成与验证;配合命令与代码片段,并指出常见陷阱与最佳实践。


总览与原则

  • 目标:提供数据的保密性、完整性、认证与不可否认性;在工程中正确选型与安全使用。
  • 通用原则:
    • 使用经过审计的库与默认安全配置;避免自实现低层算法。
    • 首选 AEAD(如 AES-GCM/ChaCha20-Poly1305)、强随机数(CSPRNG)、强哈希(SHA-256/512、SHA-3)。
    • 关注密钥生命周期与管理:生成、存储、轮转、吊销与审计(KMS/HSM/秘密管理)。

保密性 完整性 数据 加密 HMAC/签名 安全传输 验证


哈希(SHA 系列)

  • 定义:输入任意长度消息,输出固定长度摘要;满足抗碰撞、抗第二原像与单向性。
  • 常用:SHA-256/512(SHA-2)、SHA3-256/512(SHA-3)。
  • 用途:
    • 完整性校验(配合签名或 HMAC);密码存储(需加盐 + 专用函数如 Argon2/PBKDF2/bcrypt/scrypt)。
    • 指纹与标识(证书指纹、文件校验)。
  • 误区:
    • 单独哈希不提供认证,容易被替换;需要 HMAC 或数字签名。

示例(浏览器 SubtleCrypto):

js 复制代码
const digest = async (msg) => {
  const enc = new TextEncoder().encode(msg);
  const hash = await crypto.subtle.digest('SHA-256', enc);
  return Array.from(new Uint8Array(hash)).map(b=>b.toString(16).padStart(2,'0')).join('');
};

HMAC(基于哈希的消息认证码)

  • 作用:提供完整性与认证(密钥持有者可验证)。常见 HMAC-SHA256/HMAC-SHA1(逐步淘汰)。
  • 原理(简化):HMAC(K, m) = H( (K ⊕ opad) || H( (K ⊕ ipad) || m ) )
  • 用途:
    • API 请求签名、TURN 临时凭证(用户名+时间戳 的 HMAC)、Webhook 验证。
  • 误区:
    • 密钥管理不当、时间戳与时区错误导致过期判断失效;截断长度过短易被暴力。

Client Server msg, HMAC(K,msg) 计算 HMAC(K,msg) 验证通过/拒绝 Client Server

示例(Node.js):

js 复制代码
import crypto from 'crypto';
function hmacSha256(key, msg) {
  return crypto.createHmac('sha256', key).update(msg).digest('hex');
}

对称加密(AES 及模式)

  • AES 模式:
    • CBC:需随机 IV,易受填充攻击;不提供完整性,实际应配合 HMAC;不再推荐。
    • CTR:流模式,需唯一 nonce;不自带完整性;慎用。
    • GCM:AEAD 模式(加密 + 鉴别);需唯一 nonce;现代首选。
    • ChaCha20-Poly1305:AEAD,在无硬件 AES 加速或移动端常优于 GCM。
  • 关键点:
    • nonce/IV 管理:GCM/ChaCha20 需保证唯一性;重复 nonce 将破坏安全性。
    • 认证数据(AAD):如协议头部,可加入鉴别但不加密。

示例(Node.js AES-GCM):

js 复制代码
import crypto from 'crypto';
function aesGcmEncrypt(key, plaintext, aad) {
  const iv = crypto.randomBytes(12); // GCM nonce
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  if (aad) cipher.setAAD(aad);
  const enc = Buffer.concat([cipher.update(plaintext), cipher.final()]);
  const tag = cipher.getAuthTag();
  return { iv, enc, tag };
}
function aesGcmDecrypt(key, {iv, enc, tag}, aad) {
  const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
  if (aad) decipher.setAAD(aad);
  decipher.setAuthTag(tag);
  return Buffer.concat([decipher.update(enc), decipher.final()]);
}

非对称密码:RSA、ECDSA/Ed25519、ECDH

  • 功能划分:
    • 加密(密钥协商/交换):RSA-OAEP、ECDH(椭圆曲线 Diffie-Hellman)。
    • 签名与验证:RSA-PSS、ECDSA(P-256/SECP256R1)、Ed25519(EdDSA)。
  • 推荐:
    • 签名:RSA-PSS 或 Ed25519;验证速度快,参数简单。
    • 密钥协商:ECDH(P-256/P-384)或基于 TLS 的 ECDHE。
  • 误区:
    • RSA-PKCS#1 v1.5 加密已不推荐;签名模式需区分(PSS vs v1.5)。
    • 曲线选择要遵循平台支持(浏览器常用 P-256;Ed25519 在 WebCrypto 支持有限)。

示例(OpenSSL 生成 RSA 与签名):

bash 复制代码
# 生成 RSA 私钥(2048以上)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rsa.key
# 派生公钥
openssl pkey -in rsa.key -pubout -out rsa.pub
# 签名与验证(SHA-256 + PSS)
openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sign rsa.key -out msg.sig msg.bin
openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -verify rsa.pub -signature msg.sig msg.bin

随机数与熵源

  • 原则:使用 CSPRNG(操作系统提供):/dev/urandom(Linux/Unix)、CryptGenRandom/BCryptGenRandom(Windows)、crypto.getRandomValues(Web)。
  • 禁止:Math.random() 或非加密安全的 PRNG 做密钥/nonce。
  • 注意:
    • 唯一性与不可预测性;GCM/ChaCha20 nonce 必须唯一。
    • 种子管理:避免固定种子;测试环境与生产区分。

示例(Web):

js 复制代码
const key = crypto.getRandomValues(new Uint8Array(32));
const nonce = crypto.getRandomValues(new Uint8Array(12));

X.509 证书:结构、生成与验证

  • 结构要点:
    • Subject/Issuer、Serial、Validity(NotBefore/NotAfter)、SubjectAltName(DNS/IP)、KeyUsage/ExtendedKeyUsage。
    • 公钥算法(RSA/ECDSA)、签名算法(SHA256withRSA 等)。
  • 链与验证:
    • 证书链(Leaf→Intermediate→Root);验证域名(SAN)、有效期、撤销(OCSP/CRL)、信任存储。
  • 实践:
    • 服务端证书(TLS/DTLS)用于握手与身份;WebRTC 的 DTLS 指纹(a=fingerprint)绑定证书哈希用于会话验证。

示例(OpenSSL 自签与 CSR):

bash 复制代码
# 生成 ECDSA 私钥(P-256)
openssl ecparam -genkey -name prime256v1 -noout -out ecdsa.key
# 生成 CSR(包含 SAN)
cat > csr.conf <<'EOF'
[ req ]
prompt = no
distinguished_name = dn
req_extensions = req_ext
[ dn ]
CN = your-domain.example
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = your-domain.example
EOF
openssl req -new -key ecdsa.key -out ecdsa.csr -config csr.conf
# 自签证书(开发用,不推荐生产)
openssl x509 -req -in ecdsa.csr -signkey ecdsa.key -days 365 -out ecdsa.crt -extensions req_ext -extfile csr.conf

验证链 站点证书 中间CA 根CA 客户端信任存储


从原理到实践:工程清单

  • 选型与配置:
    • 哈希:SHA-256/512、SHA3,密码存储使用 Argon2/PBKDF2。
    • HMAC:请求签名、临时凭证;校时与时区;签名长度≥128位。
    • 对称:优先 AES-GCM/ChaCha20-Poly1305;严格管理 nonce;使用 AAD。
    • 非对称:签名用 RSA-PSS/Ed25519;协商用 ECDH(ECDHE)。
    • 随机数:系统 CSPRNG;禁止 Math.random 用于密钥生成。
    • 证书:SAN 与 EKU 配置正确;自动续期与吊销检查;DTLS 指纹校验。
  • 密钥管理:
    • 使用 KMS/Secrets Manager/HSM 管理密钥;审计访问与轮转;分环境隔离。
  • 安全部署:
    • 强制 TLS ≥ 1.2;禁用弱套件;启用 HSTS/CSP;最小权限与短期凭证。
  • 常见陷阱:
    • 重复 nonce(GCM/ChaCha20)导致灾难性泄露;
    • 使用旧模式(RSA v1.5、AES-CBC 无 MAC);
    • 证书域名与 SAN 不匹配;
    • 时间与随机源问题导致 HMAC/证书校验异常。

关联到 WebRTC 的实践(速链)

  • DTLS 指纹:a=fingerprint 传递证书哈希,防中间人;必须通过已鉴权与加密的信令通道。
  • 媒体安全:SRTP(AES-CTR/HMAC 或 AES-GCM AEAD),现代实现倾向 AEAD。
  • TURN 凭证:使用 HMAC 的短期用户+口令(TURN REST),避免静态凭证滥用。
  • 浏览器随机:crypto.getRandomValues;候选隐私:mDNS。

延伸参考

  • NIST 与 IETF:AES-GCM、ChaCha20-Poly1305、HMAC、SHA-2/3、RSA-PSS、Ed25519、X.509、OCSP/CRL。
  • 工具与库:OpenSSL、BoringSSL、libsodium、Node.js crypto、WebCrypto API。
  • 实践指南:OWASP ASVS/Cheat Sheets、TLS 配置最佳实践。

总结:理解"保密性/完整性/认证"的目标,选用现代算法与安全模式(AEAD、强哈希、强随机),再把密钥与证书管理、时间与身份策略落实到工程细节,才能让系统在真实网络与对抗面前保持稳健与可审计。


深入原理与关系映射

哈希的内部原理与安全性质

  • Merkle--Damgård(SHA-2):对消息分块迭代压缩,末尾添加长度与填充;易受"长度扩展攻击",因此带密钥的完整性校验应使用 HMAC,而非"secret-prefix MAC"。
  • Sponge(SHA-3):吸收/挤压(absorb/squeeze)结构,抗长度扩展;适用于新设计场景。
  • 安全性质:抗碰撞(难找到 m1≠m2 且 H(m1)=H(m2))、抗第二原像、单向性。

HMAC 的抗攻击能力与构造意义

  • HMAC 通过两次哈希与内外填充(ipad/opad)抵御长度扩展与某些结构攻击;只要底层哈希为抗碰撞且密钥保密,HMAC 即具认证性。
  • 与数字签名区别:HMAC 需要共享秘密,适合"对称认证";签名适合"公开验证与不可否认"。

对称加密的安全模型与 AEAD

  • 语义安全(IND-CPA):攻击者在已知明文模型下无法区分密文;CTR/CBC 满足保密但不提供完整性。
  • 抗主动攻击(IND-CCA):需要认证的加密(AEAD)。GCM 内含 GHASH(多项式 MAC),Poly1305 为消息认证码;重复 nonce 会破坏安全(GCM 泄露密钥相关信息)。
  • AAD(Associated Data):如协议头部,加入认证但不加密,确保整体完整性。

非对称的数学基础与实践要点

  • RSA:基于模幂与因数分解困难;加密需 OAEP 填充,签名首选 PSS;v1.5 过时且易被利用。
  • ECDSA/Ed25519:椭圆曲线上的签名;ECDSA 若重复或泄露随机数 k 将暴露私钥,建议使用 RFC 6979(确定性签名)。Ed25519 设计简洁且高效,但平台支持需确认。
  • ECDH/ECDHE:基于离散对数困难;用于协商共享秘密,再派生对称密钥;注意小子群攻击与曲线选择(P-256/Curve25519)。

随机性的本质与风险

  • CSPRNG 保证输出不可预测;初始熵不足(特别是嵌入式设备)会导致低安全度,需合并多源熵(TRNG+系统事件)。
  • nonce/IV 的唯一性要求:重复将破坏 AEAD 安全;常用 96-bit GCM nonce 与 32-bit/64-bit 计数器结合确保唯一。

X.509 与 PKI 的信任链

  • 信任锚(Root CA)→中间 CA→站点证书;客户端验证 SAN、有效期与链完整性;OCSP/CRL 用于撤销。
  • WebRTC 的 DTLS 指纹:SDP 中的 a=fingerprint 为证书哈希,双方在握手前就"固定指纹",防止中间人修改证书。

典型协议映射:TLS/DTLS 与 WebRTC

Client Server TLS/DTLS 握手:使用证书与签名认证身份,使用 ECDHE 协商密钥 ClientHello (随机数, 套件支持) ServerHello + Certificate (X.509) ServerKeyExchange (ECDHE) ClientKeyExchange (ECDHE) Finished (HMAC/MAC 验证) Finished 派生对称会话密钥,数据平面使用 AEAD (AES-GCM) Client Server

选择与对比(速查)

  • 签名:优先 RSA-PSS/Ed25519(视平台支持);避免 RSA v1.5。
  • 加密:优先 AEAD(AES-GCM/ChaCha20-Poly1305);避免 CBC+无 MAC。
  • 哈希:SHA-256/512 或 SHA-3;带密钥校验使用 HMAC。
  • 随机:系统 CSPRNG;确保 nonce 唯一性。
  • 证书:SAN/EKU 正确,自动续期与撤销;指纹校验。

从零搭建安全通道(实操路径)

  • 生成证书与指纹,配置 TLS/DTLS;
  • 选择 AEAD 与套件,设定最低 TLS 版本与禁用弱套件;
  • 使用 HMAC 为临时凭证与 API 请求签名;
  • 使用系统 CSPRNG 生成密钥与 nonce,记录并保证不重复;
  • 配置日志与审计,定期轮转密钥与证书。
相关推荐
拾忆,想起14 小时前
10分钟通关OSI七层模型:从光纤到APP的奇幻之旅
java·redis·网络协议·网络安全·缓存·哈希算法
HY小海16 小时前
【C++】9.哈希表实现
数据结构·哈希算法·散列表
小柯博客1 天前
交叉编译aws kvs webrtc
webrtc
赖small强1 天前
【ZeroRange WebRTC】WebRTC 访问控制:最小权限与短期凭证(深入指南)
webrtc·房间/频道·短期令牌·临时凭证
RTC老炮1 天前
webrtc降噪-NoiseEstimator类源码分析与算法原理
算法·webrtc
赖small强1 天前
【ZeroRange WebRTC】在自有 AWS 环境实现与 Amazon KVS 等效的 WebRTC 安全方案(落地指南)
安全·webrtc·aws·访问控制·信令安全·媒体安全·监控与合规
今天也想MK代码2 天前
WebRtc语音通话前置铃声处理
ffmpeg·webrtc
huangql5202 天前
WebRTC技术详解:构建实时音视频应用实践
webrtc·实时音视频
赖small强2 天前
【ZeroRange WebRTC】TWCC 在 WebRTC 中的角色与工作原理(深入指南)
webrtc·rtp·twcc·remb