发布时间:2025-12-10 21:30:44 浏览次数:3
根据本人调试ss的经验,写出本文,以便让自己不会忘记ss协议的实现细节。这里ss用缩写,是因为写全了过不了审核,懂的自然懂。
ss的密码,这个在配置ss连接的时候会用到
aes-256-gcm,这是加密方式,此外还有aes-128-gcm、aes-192-gcm、chacha20-ietf-poly1305、xchacha20-ietf-poly1305,因为时间有限我只研究了aes-256-gcm
密钥,根据password和method生成
method决定key的长度,例如aes-256-gcm就是32字节
第一个16字节 = md5(password)
第二个16字节 = md5(md5(password) + password)
参考代码:CryptServiceImpl#getKey
盐,也称为IV,在aes-256-gcm中为32字节
子密钥,根据key和salt生成,aes-256-gcm是32字节
具体怎么生成的,我也不是特别清楚,好像跟HKDF(SHA1)有关
参考代码:CryptServiceImpl#genSubkey
标签,aes-256-gcm中每次加密都会生成一个16字节的tag,具体干嘛用的我也不知道
不知道怎么称呼它,在aes-256-gcm中它是12字节byte数组,每次加密都会使最前面的byte加1,前面的byte满了会让下一个byte加1
每一次请求,都先会产生一个随机的32字节salt
根据password和method,可以产生key
根据key和salt,可以产生subkey
根据method、nonce、subkey,可以将明文变成密文
下面是具体加密流程
数据按最大0x3fff字节分块,每一块将长度明文加密,生成一个tag,nonce递增,数据内容明文加密,生成一个tag,nonce递增。一直这么处理,直到数据全部加密完毕
最后的结构如下所示:
注意:每一次请求只会有一个salt,不管本次请求数据有多长salt都是不会变的。不同的请求salt是不同的。
每一次请求,在aes-256-gcm中都先取出头部32字节salt
根据password和method,可以产生key
根据key和salt,可以产生subkey
根据method、nonce、subkey,可以将密文变为明文
具体解密流程,就是先取2+16字节,解密解析出长度,再取长度+16字节,解密解析出内容
将所有内容拼起来就是解密后的结果
ss头部与加密解密无关,因为正常的数据中只有请求数据,而没有请求服务器的地址,所以在请求数据的头部加了1+n+2个字节表示请求服务器的地址
ss头部格式如下图所示
ss头部与正常请求数据结合在一起形成明文,和加密解密中的salt一样,ss头部每次请求也只有一个
一图胜万言
ss
感谢github上面的相关代码,这里我就不贴了,贴了过不了审核