安全基石:加密算法选型(AES、RSA、ECC)、哈希函数与数字签名在SDK中的应用
加密算法选型,说白了就是在给SDK打地基。地基不稳,上面功能再花哨也是白搭。我这些年看过的密钥泄漏案例,十有八九不是算法被攻破,而是选型或使用姿势不对。今天我们就聊聊对称加密、非对称加密、哈希和数字签名,在SDK里到底该怎么落地。
对称加密:AES 仍然是首选
AES 目前是行业标准,NIST 认证过,硬件加速也普遍支持。我个人习惯在 SDK 的本地缓存加密、会话密钥派生等场景里固定用 AES-256-GCM。为什么?
- 安全性:GCM 模式提供认证加密,同时防篡改。
- 性能:相比 Cipher Block Chaining (CBC) 模式,GCM 能并行处理,现代 CPU 有 AES-NI 指令集,速度很快。
- 推荐参数:密钥长度 256 位,Nonce 12 字节,Tag 16 字节。
非对称加密:RSA 还是 ECC?
RSA 和 ECC 都是主流,但适用场景不同。你想想看,RSA 的密钥对生成慢,签名验签也慢,但兼容性最好,很多老旧系统只认 RSA。ECC(椭圆曲线)呢?相同安全强度下密钥短、速度快,更适合移动端和 IoT 设备。
| 特性 | RSA-2048 | ECC-P256 |
|---|---|---|
| 密钥长度 | 2048 bits | 256 bits |
| 签名速度(相对) | 慢 | 快 |
| 验签速度(相对) | 较快 | 快 |
| 安全强度 | 112 bits | 128 bits |
| 兼容性 | 极高 | 中 |
| 推荐场景 | 服务端签名、老旧系统 | 移动端、密钥交换 |
在 SDK 里,我建议用 ECC 做密钥交换和数字签名,除非有强制合规要求。注意曲线选择要规范,例如 NIST P-256 或 Curve25519,别自己定义。我曾经见过有人用 secp256k1(比特币曲线)做通用签名,结果标准接口不兼容,导致验签失败。
哈希函数:别只记得 SHA-256
哈希不只是摘要计算。它在 SDK 里至少有三个用途:
- 完整性校验:验证数据在传输、存储中是否被篡改。
- 密钥派生:配合 HKDF 或 PBKDF2 从主密钥派生子密钥。
- 数字签名的基础:先哈希再签名,避免直接对大块数据签名。
常用的哈希族是 SHA-2(SHA-256/384/512),SHA-1 已经废弃 不要用。对于密码存储,要用专门的慢哈希如 bcrypt、scrypt 或 Argon2,别用 SHA-256 裸算。
数字签名:签名 ≠ 加密
很多新人容易把签名和加密搞混。签名是用私钥对消息摘要加密,任何人可以用公钥验证。它保证的是 不可否认性 和 完整性,不是机密性。
在 SDK 中,数字签名常见的场景:
- 代码包签名(防止分发过程中被植入后门)
- 令牌签名(JWT、Session )
- 日志审计签名(确保审计记录不被篡改)
具体做法:先对数据做 SHA-256 哈希,再用私钥对哈希值签名,输出签名值。验签时计算同样的哈希,用公钥验证签名是否匹配。
// Go 示例:使用 ECDSA P256 签名
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
)
func sign(data []byte, privateKeyPEM []byte) ([]byte, error) {
// 1. 解析私钥
block, _ := pem.Decode(privateKeyPEM)
priv, err := x509.ParseECPrivateKey(block.Bytes)
// 2. 哈希
hash := sha256.Sum256(data)
// 3. 签名
r, s, _ := ecdsa.Sign(rand.Reader, priv, hash[:])
signature := append(r.Bytes(), s.Bytes()...)
return signature, nil
}
整个加密体系长什么样?
我把对称加密、非对称加密、哈希和签名之间的协作关系画成了下面这张图。你看一眼就明白了。
避坑指南:实战中的三个教训
教训一:混淆密钥用途
我曾经见过一个 SDK,用同一对 RSA 密钥既做加密又做签名。攻击者拿到密文后,利用签名接口间接解密。一定要严格隔离密钥用途:加密密钥和签名密钥分开管理。
教训二:哈希+签名顺序错误
有人先签名后哈希,结果验签效率极低且容易被中间人绕过。正确顺序是:数据 → 哈希 → 签名。验签时先对收到的数据做同样哈希,再用公钥验证签名。
教训三:硬编码密钥
这是最蠢的错误,但也是最常见的。SDK 里绝不能把私钥写在配置或代码里。我曾审计一个项目,密钥直接 base64 编码嵌在 Android APK 里,反编译一下就能提取。正确的做法是用 KMS API 或密钥链(Keychain)按需获取。
总结:选型决策矩阵
| 算法 | 用途 | SDK 内典型实现 | 我的推荐 |
|---|---|---|---|
| AES-256-GCM | 数据加密、会话密钥加密 | crypto/aes + crypto/cipher (Go) | 首选对称加密方案 |
| ECC P-256 | 数字签名、密钥交换 | crypto/ecdsa (Go) | 移动端/低功耗设备 |
| RSA-3072 | 兼容场景、证书签名 | crypto/rsa (Go) | 企业合规场景 |
| SHA-256 | 完整性校验、摘要 | crypto/sha256 | 基础哈希标配 |
| ECDSA / Ed25519 | 签名与验签 | crypto/ed25519 (Go) | 性能敏感场景推荐 |
好了,这一章先到这里。选对算法只是第一步,后面我们还要聊密钥生命周期管理和权限模型。希望刚才那些踩过的坑能帮你少走弯路。