之前搞TLS的过程中,PSK的概念有所了解,但是一直觉得他没什么用处,就大致看了一下实现,没深究。但是TLS1.3中居然设计到了PSK的概念,我想有必要在这里总结一下,以免忘记。(其实就我个人而言,要理解TLS 1.3的session resume原理,是不需要理解PSK的,anyway,就当记录了)
RFC 4279中详细描述了各个方面。
###PSK-only
简单的说,就是client写死一个key,server写死一个key,当然这两个key是一样的。key肯定不能用于传输,因为如果key被明文传输了还有什么意义?所以每个 key 都有其对应的一个 psk identity。
其次 这个key被用来当做pms(pre master key)的一部分。
客户端会发送client key exchange,client key exchange中携带有一个字符串:identity,server收到identity,查找identity对应的key,这样就能知道客户端使用的是那个key了。
我们知道,其他的非PSK算法,client key exchange解出来的48字节的值,就是pms,但是PSK时,不一样,假设我们设置的key是"0x12345678",4字节,那么我们的pms是:
00 04 00 00 00 00 00 04 12 34 56 78,一共12字节。
RFC上这么描述premaster 的生成:
The premaster secret is formed as follows: if the PSK is N octets
long, concatenate a uint16 with the value N, N zero octets, a second
uint16 with the value N, and the PSK itself.
struct {
opaque other_secret<0..2^16-1>;
opaque psk<0..2^16-1>;
};
Here "other_secret" either is zeroes (plain PSK case) or comes
from the Diffie-Hellman or RSA exchange (DHE_PSK and RSA_PSK,
respectively).
这里,我们的other_secret填写的是0。之后的流程,就如其他算法一样,这里不再描述。
正如上面所说,client key exchange携带的是identity,其实就是key对应的标识。服务器肯定也有该标识对应的key,这样才能协商成功。
###PSK-RSA
这个我个人觉得比较累赘,RFC上说了他的用处,大家可以看看,我没啥耐心。
PSK-only中,key是两端配置写死的,那么在PSK-RSA中呢,key也需要配置。
先看报文:
报文的流程,和标准的RSA流程一模一样。
我们细看client key exchange报文:
它和标准的就多了一个identity域,其他的比如Encrypted premaster就和标准的算法一样。
对于标准的RSA,Encrypted premaster包含了48字节(去掉padding后)的random,用作pre master key,显然PSK之所以叫做PSK,我们肯定不能简简单单的和标准RSA一样,把Encrypted premaster解开,提取出的值就是pre master key。
PSK-RSA中的pre master key 其实定义和PSK-only中的一样
struct {
opaque other_secret<0..2^16-1>;
opaque psk<0..2^16-1>;
};
Here "other_secret" either is zeroes (plain PSK case) or comes
from the Diffie-Hellman or RSA exchange (DHE_PSK and RSA_PSK,
respectively).
举个例子,Encrypted premaster我们解密开是a-xA-X,48字节,那么我们的pre master key 就是
00 30 a-xA-X 00 04 12 34 56 78 ,共56字节。
剩余的流程,和其他标准算法一样。
###PSK-DHE、PSK-ECDHE
这个就不多说了,握手流程和标准的DHE和ECDHE一样,只是client key exchange和server key exchange不一样罢了。
注:server key exchange 有个"PSK identity hint"这里没细究。
通过标准的握手,从pubkey中提取出标准的pre msater key,然后添加我们设置的key,就如PSK-RSA一样就行了。