HarmonyOS 7 ECIES 混合加密的密钥协商与消息封装机制【鸿蒙心迹】
非对称加密为什么不能直接拿公钥把整个大文件加密掉?

做端到端聊天的时候,最开始的思路很简单:把对方公钥拿过来,把消息加密了发过去不就行了?
结果真做的时候发现不对:公钥加密是快,但加密的长度有限制。一条消息还能凑合,一张图片、一个大文件,公钥根本加不动。
那为什么微信、Telegram 这些端到端加密,大文件也能加密?它们是怎么做的?
一、先想清楚:为什么非对称加密不能直接加密大文件
先把最基础的问题想明白。
非对称加密,比如 RSA,它加密的原理是数学运算。这个运算本身就有长度限制。RSA 2048 位的密钥,一次最多也就加密两百多字节。你要加密一个 1MB 的文件,根本塞不进去。
| 加密方式 | 加密速度 | 能加密多大 |
|---|---|---|
| 非对称加密 | 慢 | 几百字节 |
| 对称加密 | 快 | 任意大小 |
对称加密,比如 AES,速度快,加密多大文件都行。但对称加密有个问题:密钥怎么安全地传给对方?
这就矛盾了:非对称加密安全但慢,对称加密快但密钥传不过去。
那怎么办?
二、ECIES 到底是什么
ECIES 不是一种新的加密算法。它是一个组合方案:用非对称算法做密钥协商,生成一个共享密钥,然后用这个共享密钥做对称加密。
说白了就是:非对称加密负责"安全地把密钥传过去",对称加密负责"把真正的数据加密"。
完整流程是这样的:
- 双方各生成一对 ECC 密钥对;
- 用对方公钥和自己私钥做 Key Agreement,生成一个共享秘密;
- 用 KDF 从这个共享秘密派生一个对称密钥;
- 用这个对称密钥做 AES-GCM 加密;
- 把加密后的临时公钥和密文一起发过去。
这段代码解决什么问题: 完整 ECIES 加密流程。
文件: crypto/EciesManager.ets
用途: 端到端加密
接入位置: 聊天消息发送
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
// 第一步:生成 ECC 密钥对
let ecc = cryptoFramework.createAsyKeyGenerator('ECC256');
let keyPair = await ecc.generateKeyPair();
// 第二步:Key Agreement 生成共享秘密
let keyAgreement = cryptoFramework.createKeyAgreement('ECC');
let sharedSecret = await keyAgreement.generateSecret(keyPair.priKey, peerPubKey);
// 第三步:KDF 派生对称密钥
let kdf = cryptoFramework.createKdfX963KDF('SHA256');
let keyMaterial = await kdf.deriveKey(sharedSecret, 32);
// 第四步:AES-GCM 对称加密
let cipher = cryptoFramework.createCipher('AES256-GCM');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyMaterial, {
iv: nonce,
tagLen: 16
});
let cipherText = await cipher.doFinal(plainText);

三、每一层到底在干嘛
我们一层一层拆,看看为什么需要这么多层。
第一层:ECC 密钥对
为什么用 ECC 不用 RSA?因为 ECC 同样安全强度下,密钥更短,运算更快。ECC 256 位的安全强度,大概相当于 RSA 3072 位。手机上做加密,性能很重要,ECC 更合适。
第二层:Key Agreement
Key Agreement 是什么意思?就是:我用我的私钥和你的公钥,你用你的私钥和我的公钥,算出来一个一样的数。这个数只有我们俩知道,别人算不出来。
这就是共享秘密。它是通过数学运算出来的,不是传过去的。所以安全。
第三层:X963KDF
为什么有了共享秘密还要 KDF?因为共享秘密的长度、格式,不一定正好符合对称密钥的要求。
KDF 的作用就是:把这个共享秘密,派生成一个符合要求的对称密钥。还可以加一些别的信息进去,让密钥更随机更安全。
第四层:AES-GCM
为什么用 GCM 不用 ECB?因为 GCM 不仅加密,还做完整性校验。密文被改了,解密的时候直接就报错了。不用再单独做签名。
四、几个容易踩的坑
第一个坑:把 ECIES 当成"另一种 RSA"。它本质是混合加密,不是单一算法。
第二个坑:直接长期保存派生后的共享密钥。派生出来的密钥用完就该丢,不要存。
第三个坑:重复使用 IV/Nonce。AES-GCM 的 Nonce 重复了,安全性就崩了。每次加密都要新的 Nonce。
第四个坑:公钥来源不可信。公钥是谁的?怎么证明是对方的?这个信任链很重要。
第五个坑:加密和签名混为一谈。加密是防别人看,签名是防别人改。两件事。
五、解密失败怎么处理
解密失败的情况太多了:Nonce 不对、密钥不对、密文被改了、数据传错了。
正确的做法是:解密失败就直接报安全错误,不要猜是什么原因,不要降级处理。安全相关的东西,宁可失败也不要放行。

这次做端到端加密最大的体会是:ECIES 不是一个黑盒算法,是一套组合方案。非对称算法负责安全地传密钥,对称算法负责快速加密数据。每一层都有它存在的理由,不是为了凑数。
真正做的时候,最容易忽略的不是算法本身,而是周边的东西:Nonce 随机、密钥生命周期、公钥信任、错误处理。这些才是安全的关键。
更多推荐



所有评论(0)