非对称加密 RSA 与国密 SM 系列

本节目标

非对称加密有两把钥匙:公钥(公开,用来加密/验签)和私钥(保密,用来解密/签名)。前端通常只持有公钥,所以常用来「用公钥加密,只有服务端私钥能解密」或「服务端用私钥签名,前端用公钥验签」。

// 运行环境:Node.js 18+(无需依赖,用内置 crypto)
// 运行:node jsr-l9.cjs
const crypto = require('crypto')
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 })
const data = '敏感数据'
// 公钥加密
const enc = crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64')
console.log('密文:', enc)
// 私钥解密
const dec = crypto.privateDecrypt(privateKey, Buffer.from(enc, 'base64')).toString('utf8')
console.log('明文:', dec)

// 常见逆向场景:前端用「硬编码的公钥」加密,你复现加密即可(解密在服务端)
// 识别:搜 'RSA' / 'encrypt' / 'PUBLIC KEY' / 'jsencrypt' 库

国密 SM 系列:国内常用。SM2(非对称,类 RSA)、SM3(哈希,类 SHA256)、SM4(对称,类 AES)。逆向里遇到「sm2/sm3/sm4」「gmssl」「crypto-js 的 sm 扩展」要能认出来。Node 原生不直接支持 SM,需用 sm-crypto 等库复现。

名词解释

非对称加密(Asymmetric Encryption):用「公钥 + 私钥」一对钥匙。公钥可公开,私钥必须藏好。典型用法:A 用 B 的公钥加密,只有 B 的私钥能解——适合「前端加密、服务端解密」。它解决了对称加密「密钥怎么安全传递」的难题,但速度慢,所以常和对称加密配合(用 RSA 传 AES 的密钥)。

国密(SM 系列):中国自主设计的密码算法族。SM2≈RSA(非对称)、SM3≈SHA256(哈希)、SM4≈AES(对称)。在政务、金融、国内大厂接口里常见。逆向识别关键:看到 sm2/sm3/sm4 关键字或 sm-crypto 库,就知道要走国密复现路线,别拿 AES/RSA 的 API 硬套。

课后练习

练习 1:前端只有「公钥」能做什么、不能做什么?

答案:能用公钥「加密数据」(只有服务端私钥解)或用公钥「验签」(确认数据来自持有私钥的服务端)。不能「解密」别人发来的密文(没私钥),也不能「伪造签名」(没私钥)。所以前端逆向遇到 RSA,通常只需复现「公钥加密」或「公钥验签」。

练习 2:为什么 RSA 常和 AES 配合使用,而不是全程 RSA?

答案:RSA 算得慢,不适合加密大块数据。常见做法是「用 RSA 加密一把临时 AES 密钥,再用 AES 加密正文」——又快又安全。逆向时要注意:密文可能分两段,一段是 RSA 包着的密钥,一段是 AES 正文。

总结

非对称加密在逆向里的「角色」和对称加密完全不同,这点必须先想清。我的观点:前端若只持公钥,那它根本不想防你复现加密——它防的是「中间人」。所以你复现「公钥加密」几乎必然成功,难点只在「把公钥和参数对齐」。真正麻烦的是国密 SM 系列:Node 原生不支持,你得装 sm-crypto 这类库,而且 SM2/SM3/SM4 的调用方式和 RSA/AES 不一样,照着 AES 的 API 抄必错。我的建议是:遇到国密先确认具体是哪个(SM2/3/4),再去找对应库的「最小可运行示例」对照,别凭记忆硬写。