RSA 为什么只能加密小块数据
RSA 的安全性建立在模幂运算上,一次运算的输出必须小于模数,所以能加密的明文长度有硬上限。2048 位密钥配合 OAEP 填充与 SHA-256 时上限约 190 字节,4096 位也只有 446 字节。因此实际系统不会用 RSA 直接加密业务数据,而是用它包装一把随机对称密钥(信封加密),正文交给 AES 之类的对称算法处理:对称算法快几个数量级,且没有长度瓶颈。
长度上限速查
| 上限公式 | k - 2*hLen - 2(k 为模长字节数,hLen 为散列输出字节数) |
|---|---|
| 2048 位 + SHA-256 | 256 - 64 - 2 = 190 字节 |
| 4096 位 + SHA-256 | 512 - 64 - 2 = 446 字节 |
| 实际做法 | RSA 只加密一把 32 字节的 AES-256 密钥 |
| 填充要求 | 新系统必须用 OAEP;PKCS#1 v1.5 加密已不推荐 |
| 性能对比 | 对称加密比 RSA 快几个数量级,数据量大时差距更明显 |
典型使用场景
- 文件与消息加密:RSA 包装会话密钥,正文用 AES-GCM 加密并附认证标签
- 对接遗留系统:对方只支持 RSA 密钥传输时,在应用层按信封结构改造
- 大字段入库加密:不要逐个字段调 RSA,改为在应用层用一把数据密钥批量加密
- 密钥分发:把对称密钥加密后随配置文件或消息一起下发,避免明文传输
混合加密流程(伪代码)
混合加密流程(伪代码)
# 发送方
# 1) 生成随机的 AES-256 密钥 K 与 12 字节 IV
# 2) 用 K 以 AES-GCM 加密数据,得到密文与认证标签 tag
# 3) 用接收方 RSA 公钥(OAEP + SHA-256)加密 K,得到封装密钥
# 4) 传输 {封装密钥, IV, 密文, tag},字段长度与顺序必须固定
# 接收方
# 5) 先用私钥解出 K;解失败直接拒绝,不要回退其它填充方式
# 6) 再用 K 与 IV 解密并校验 tag,tag 不符立即丢弃模长与明文上限
| 模长 | OAEP+SHA-256 上限 | 典型用途 |
|---|---|---|
| 2048 位 | 190 字节 | 包装 32 字节 AES 密钥绰绰有余 |
| 3072 位 | 318 字节 | 过渡期推荐的最小合规长度 |
| 4096 位 | 446 字节 | 长期根密钥,解密耗时更高 |
TLS 1.3 已移除 RSA 密钥传输,改用 (EC)DHE 协商会话密钥;但信封加密思路仍适用于文件加密、消息系统与遗留接口。
上限公式里的 hLen 随散列变化:换成 SHA-1 会得到 214 字节的上限,但 SHA-1 不应再用于新系统;换成 SHA-512 上限会降到 126 字节。散列选择会直接改变可用载荷,升级前要回归测试。
解密失败的处理方式很关键:OAEP 解密失败必须整体拒绝并记日志,不能降级尝试其它填充,也不能区分「填充错误」与「内容错误」,否则等于把填充预言机暴露给攻击者。