开发必懂的文件加解密

背景
最近团队遇到一个小需求,存在两个系统 A、B,系统 A 支持用户在线制作皮肤包,制作后的皮肤包用户可以下载后,导入到另外的系统 B 上。皮肤包本身的其实就是一个 zip 压缩包,系统 B 接收到压缩包后,解压并做一些常规的校验,比如版本、内容合法性校验等,整体功能也比较简单。

但没想到啊,一帮测试人员对我们开发人员一顿输出,首先绕过系统 A 搞了几个视频文件,把后缀改成 zip 就直接想上传,系统 B 每次都是等到上传完后才发现文件不合法,系统 B 在文件没上传完前又无法解压,也不知道文件内容是不是合法的,就这么消耗了大量带宽、大量时间后才提示用户皮肤包有问题。

这里涉及了两个问题,我们来捋一捋:

文件如何做加密,这样用户便无法去逆向,压缩包内部的敏感信息不会泄露出去。
服务端在接收到信息流时,在未传输完时如何去判断压缩包的合法性,提前告知用户。
AES VS RSA
说到加密,自己很多人会想到对称算法 AES 以及非对称算法 RSA。这两种算法按字面意思也较好理解,对称加密技术说白一点就是加密跟解密使用的是同一个密钥,这种加密算法速度极快,安全级别高,加密前后的大小一致;非对称加密技术则有公钥PK、私钥SK,算法的原理在于寻找两个素数,让他们的乘积刚好等于一个约定的数字,非对称算法的安全性是依赖于大数的分解,这个目前没有理论支持可以快速破解,它的安全性完全依赖于这个密钥的长度,一般用 1024 位已经足够使用。但是它的速度相比对称算法慢得多,一般仅用于少量数据的加密,待加密的数据长度不能超过密钥的长度。

使用 AES 对文件加密
结合这两种加密方式的优缺点,我们采用 AES 对文件本身做加解密,使用 AES 的原因主要考虑如下:

加解密性能问题,AES 的速度极快,相比 RSA 有 1000 倍以上提升。
RSA 对源文有长度的要求,最大长度仅有密钥长度。
AES 的加密算法 Node.js 的crypto模块中已经有内置,具体的使用可以参考官方文档。

AES 加密逻辑
const crypto = require(‘crypto’);
const algorithm = ‘aes-256-gcm’;

/**

  • 对一个buffer进行AES加密
  • @param {Buffer} buffer 待加密的内容
  • @param {String} key 密钥
  • @param {String} iv 初始向量
  • @return { {key: string, iv: string, tag: Buffer, context: Buffer}}
    */
    function aesEncrypt (buffer, key, iv) {
    // 初始化加密算法
    const cipher = crypto.createCipheriv(algorithm, key, iv);
    let encrypted = cipher.update(buffer);
    let end = cipher.final();
    // 生成身份验证标签,用于验证密文的来源
    const tag = cipher.getAuthTag();
    return {
    key,
    iv,
    tag,
    buffer: buffer.concat([encrypted, end]);
    };
    }
    复制代码
    AES 解密逻辑
    解密整体跟加密一样,只是接口换个名字即可:

const crypto = require(‘crypto’);
const algorithm = ‘aes-256-gcm’;

/**

  • 对一个buffer进行AES解密
  • @param { {key: string, iv: string, tag: Buffer, buffer: Buffer}} ret 待解密的内容
  • @param {String} key 密钥
  • @param {String} iv 初始向量
  • @return {Buffer}
    */
    function aesDecrypt ({key
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CRMEB定制开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值