CRC 校验、MAC 身份认证与 PBKDF2 密钥派生,在应用安全链路里常被称为「三板斧」。本文以 Swift CryptoSwift 为主线,逐一拆解 API 细节、示例代码、性能权衡与最佳实践,助你一次性吃透这三大 加密算法。
CRC 校验码:为你的数据装上「小快递单」
原理速览
CRC(Cyclic Redundancy Check)通过对数据块执行 多项式除法,生成高度敏感的校验值。只要 一个 bit 翻转,CRC 结果就会完全不同,因此在网络协议与固件升级中被广泛使用。
使用示例
// 1. 处理原始字节
let bytes: [UInt8] = [0x01, 0x02, 0x03]
let crc16 = bytes.crc16() // 41232
let crc32 = bytes.crc32() // 1438416925
// 2. 处理 Data
let data = Data([0x01, 0x02, 0x03])
let crc16Data = data.crc16()
let crc32Data = data.crc32()
// 3. 字符串也可一气呵成
let siteCRC16 = "hangge.com".crc16() // 0x90e7
let siteCRC32 = "hangge.com".crc32() // 0x7eeb79d1
工程考量
- 低延迟场景(如 IoT 固件升级)优先选 CRC16;
- 长文件防篡改,CRC32 碰撞概率更小;
- 别把 CRC 当加密哈希,它只负责完整性,不保证隐私。
👉 CRC 结果碰撞的实战误区与应对方案
消息认证码 MAC:「带密钥的指纹」
HMAC:最通用的 MAC
HMAC 把密钥与消息一起扔进 哈希函数,算法可无缝替换:MD5 / SHA1 / SHA256 / SHA384 / SHA512
。
let msg = "欢迎访问hangge.com"
let key = "hangge"
let hmacSHA1 = try HMAC(key: key.bytes, variant: .sha1)
.authenticate(msg.bytes)
.toHexString()
// 输出示例:3936e617b203db73d7ad3a004e03f9d053daffb1
Swap .sha384
或 .sha512
,一行代码即可提升 碰撞难度。
Poly1305:高速、短签名
Poly1305 常和 ChaCha20 搭配,每进行一次运算生成 16 字节摘要,一举解决 真实性与完整性 双验证。
let str = "欢迎访问hangge.com"
let key32 = "hg012345678901234567890123456789"
let mac = try Poly1305(key: key32.bytes)
.authenticate(str.bytes)
.toHexString()
// 64b8b90c6d407db85e3d8d40eb9d9502
选用建议
场景 | 推荐方案 |
---|---|
REST-API 签名 | HMAC-SHA256 |
QUIC / WireGuard 协议 | Poly1305 |
低功耗设备 | HMAC-SHA1(速度与安全的折中) |
PBKDF2:对抗暴力破解的「缓兵之计」
为什么要加盐
- 彩虹表秒破哈希 已从理论走进真实攻击;
- 只要盐值 随机且唯一,彩虹表长度呈指数级膨胀;
- 盐的长度建议 ≥ 32 bytes,等于哈希输出长度才是黄金比例。
核心 API 速学
let pwd = "hangge2017"
let salt = Data("Ut3Opm78U76VbwoP4Vx6UdfN234Esaz9".utf8)
// 默认 SHA256、4096 次迭代、不限定 keyLength
let derived = try PKCS5.PBKDF2(
password: pwd.bytes,
salt: salt.bytes
).calculate()
print(derived.toHexString())
进阶参数微调
参数 | 解释 | 推荐值 |
---|---|---|
iterations | 多次哈希让每秒可试密码次数大幅下降 | ≥100k |
keyLength | 输出字节数,越小越快、越长越安全 | 32 |
variant | 伪随机函数,可选 sha256 / sha512 等 | sha256 |
想把 客户端 PIN 码 升维成 256 位密钥?
👉 一步到位:把 PBKDF2 结果注入 AES-GCM 全流程
实战案例:存储用户密码的完整链路
- 随机生成 32 字节 盐值;
- 使用
PBKDF2-SHA256
,迭代 100,000 次生成 32 字节派生密钥; - 将派生密钥再输入 HMAC-SHA256 生成最终存储值;
- 入库时只需保存
<盐值, 派生密钥, 迭代次数>
,绝不存明文密码。
常见问题 FAQ
Q1:CRC 16 与 CRC32 如何选?
A:数据量 < 64 KB,用 CRC16 省字节;要兼顾跨平台兼容性,则 CRC32 更普及。
Q2:我把盐值放在客户端安全吗?
A:盐值并非机密,随机唯一 即可。真正的敏感信息是迭代次数与密钥,后端务必再做二次哈希再入库。
Q3:PBKDF2 迭代太多导致登录变慢怎么办?
A:把首次登录的派生密钥缓存到 Keychain,后续用本地派生结果对比在线挑战,平衡 UX 与安全。
Q4:Poly1305 能否替换成 ChaCha20-Poly1305 AEAD?
A:当然可以!AEAD 一次性解决加密与认证,若系统支持直接调用即可,无需手动做两次 MAC。
Q5:CryptoSwift 的 HMAC 支持异步吗?
A:当前是同步接口。对于主线程无解耦需求时可直接用;重计算场景建议放到 后台线程。
Q6:哈希输出想打印成大写 String,有没有快捷技巧?
A:在 toHexString()
后链式调用 .uppercased()
,两行代码清爽完成。
一句话总结
CRC 保证数据不翻车,MAC 确保没被「调包」,PBKDF2 把暴力破解拖进「慢动作」。
把 Swift CryptoSwift 这把瑞士军刀玩透,你的 App 就多了一道真正的钢铁长城。