flow-encryption 一个简单的流加密算法,可以用在对加密要求不高的地方,有一些场景还是非常适合的。R4C 的算法方案固然是更好的,但是实现和使用起来会比较复杂一些,对业务代码的耦合比较强。这个加密实现简单,可以直接代理中间的流量。
这个算法的应用已经迁移到迁仓库,https://github.com/traceless/alist-encrypt RC4算法目前也加入到此项应用中,也是支持RC4方式加密,安全性更好。播放跳转的时候会慢一些(后续会优化掉),但不影响正常使用。
1、关于流加密的算法有很多,基本原理都是对字节进行异或运算
,最简单的一个流加密实现就是一个固定的字节,比如 11001100 和每个字节进行异或运算,但是这样的方式就很容易被别人破解。
2、那么我们可以简单的准备一组加密的字节,比如 11001100,10001000,10011001...,如果明文的字节为 10001000,那么它对应的 encode 加密字节就为 11001100,以此类推,所以我们要准备一个明文和加密 byte 的映射
。
3、假设我们随机生成 16 个加密的字节(暂用 int 整型来标识) encode: [161 65 196 121 39 146 155 194 209 251 110 51 103 33 96 240] ,明文的后四位(0-15)就是对应 ecode 的数组的index位置
。比如明文 xxxx0001,那么它对应就是 ecode[1],如 xxxx0011 -> encode[3],以此类推,所有的明文都可以找到对应的 ecode byte。
我们可以得到明文和加密 encode 数组的映射:
明文 byte | xxxx0000 | xxxx0001 | xxxx0010 | xxxx0011 | xxxx0100 | ... |
---|---|---|---|---|---|---|
加密 byte | 10100001 | 01000001 | 11000100 | 01111001 | 00100111 | ... |
加密后 byte | xxxx0001 | xxxx0000 | xxxx0110 | xxxx1010 | xxxx0011 | ... |
密文后四位 | 1 | 0 | 6 | 10 | 3 | ... |
从上面可以得出加密后的密文的规则,比如密文等于 xxxx0001,那么它对应的 encode 加密字节就是 10100001,如:xxxx0011 -> 00100111,按照这方式进行解密即可。但是密文后四位会有冲突,很可能都会出现 xxxx0010 ^ 11000100(encode) = 6,xxxx0100 ^ 11110010(encode) = 6 ,只要找一个没有被占用的数字比如 2,然后修改 ecode byte使得密文后四位
等于 1111 0110 就可以了。
ecode 的数组生成我们可以使用 MD5 的方式进行创建,然后再生成 decode 的数组,当然解决取模冲突后,原本 encode 也会发生变化,具体看代码实现。
-
缺点:这个算法实现比较简单,破解的难度我也不好去验证,毕竟是固定的密码,通过某些流数据特征还是比较容易破解的(比如 class 文件开头的四个字节是固定的 0x CAFEBABE)。如果是单纯的暴力破解目前还是没什么机会的。另外可以根据原文件就能得到 encode 和 decode,这个解决的方案在算法优化有提到。
-
优点:算法很简单,可以嵌入到很多代理的中间件中,对流的加密不用入侵到业务代码中,可透传加解密,没有中间停留的过程。另外文件解密只要给对方 encode\decode 就可以了。
1、因为上面的是固定加密 encode,如果 encode 泄露了,那么其他的已经加密的数据也会出现问题。那么我们也可以通过流的某些属性或特征作为 MD5 的 salt,这样每次生成的密码本也会不一样。比如传输的是文件,那么文件流的长度是比较容易获取到的,可以作为 md5 的 salt。
2、目前采用的是 16 个字节,如果要换成 32 个字节,那么可能破解的难度是否增加?这个我没有去研究,毕竟 16 个字节破解的难度已经很大了,粗算大于 1.8x10^19 * 10^N(N不知道有多大,保守大于8)。
1、流密码算法有 RC4、A5/1、ZUC 等,它们的实现可能会更加安全,也可以用业内一些成熟的方案。不过还是要根据实际业务需求来使用,这些算法也许并不能满足业务需求。
因为考虑到 webdav 是基于 http 协议的,那么理论上完成 http 代理的实现就包含了 webdav 的实现了。由于只拦截 body 进行加解密,所以请求头 headers 和响应头 headers 就不需要动了,基本就是原路透传。
实现的思路:
- 解析请求头 headers,然后传到 webdav 服务器中,请求的 body 按业务进行是否加密。
- 解析响应头 headers,并原路返回到客户端中,响应的 body 按业务判断进行是否解密。
其他语言就可以根据这样的思路进行分析和拦截,node.js 提供的 http 模块非常的方便实现这样的业务。
1、httpProxy.js 是一个 http 代理服务器的最基础的实现,里面有对 http 的 body 流进行拦截加解密,可用于学习和参考。不得称赞一下 node.js 所提供 http 模块的实现,直接提供了 body 的读写流,还有 Transform 转换流接口,开发起来扛扛的。换其他语言,估计折腾大半天。
2、app.js 是一个 http 代理服务器的基本实现,可以针对性对 webdav 的流量进行挟持,使用流加密的方式可以对上传的文件,下载的文件进行加解密。也可以对一些在线视频播放的流进行实时解密。目前只代理了/dav/*的路径用于测试和验证,也可以改成代理整个 alist。
3、目前给出的 ndoejs 的 demo 版本,测试阿里云盘的上传,删除,移动,下载(302 已解决)都可以正常使用,也能正常加密和解密。配置文件参考下 config.js。
这个项目的应用已经迁移到迁仓库,https://github.com/traceless/alist-encrypt