前言
最近一段时间,一直在和PostgreSQL国际社区合作开发透明数据加密(Transparent data encryption),研究了一些密码学相关的知识,并利用这些知识和数据库相结合。本系列共分为3篇文章,上篇介绍了加密算法(关注文末二维码,往期文章不迷路);本文是第二篇,将详细介绍密钥管理;最后一篇将介绍PG中的TDE。
密钥管理由四部分构成:
密钥生成、密钥保存、密钥交换以及密钥轮转。
1
密钥生成
上篇文章介绍了我们将会选择对称分组加密方法进行加解密,那么我们的密钥即是对称密钥。而对称密码生成方法有:
随机数作为密钥
基于口令的密钥生成
HKDF(HMAC-based Extrac-and-Expand Key Derivation Function)
随机数作为密钥:这很用以理解,使用强随机数生成器,生成密钥。
基于口令的密钥生成:根据用户口令生成密钥并使用它进行加解密的方法。具体方法如下:
用户输入口令;
系统生成随机数,与用户口令进行hash计算,得到密钥加密密钥;
存储密钥加密密钥至安全处;
系统生成随机数作为数据加密密钥;
密钥加密密钥对数据密钥进行加密,同样也存储到安全处;
使用数据加密密钥对数据加解密。
3. HKDF:密钥派生函数(KDF)是密码系统的基本组成部分。它的目标是获取一些初始的密钥材料,并从中派生出一个或多个安全强度很大的密钥。
提取,使用强随机数和输入的信息使用hmac方法进行hash运算;
扩展,通过多次hash计算,对上面结果进行扩展,扩展到我们需要的长度。
2
密钥保存
密钥的生成无论是随机数的还是基于口令的,都有一部分是目前难以记忆的,所以这就需要存储密钥了(也可能是salt)。密钥不能与数据存储在同一位置,否则等于是钥匙挂在门上,没有任何意义。 我们一般需要将密钥存储在文件内,放到保险柜等安全的存储位置或者安全的密钥分配中心。 当时当密钥数量达到一定数量时,我们就需要另一种密钥,KEK(Key encryption key,密钥加密密钥)。这是由于密钥如果不进行加密,窃取后,盗取者很容易使用密钥对数据解密了。同样,管理多个密钥难度远远大于单个密钥。 所以可以考虑使用KEK来保存密钥的一种方式,当然KEK也需要存储在安全的位置。
3
密钥交换
密钥交换目前有4种:事先共享密钥,使用公钥密码,使用密钥分配中心和Diffie-Hellman密钥交换。
下面简单描述一下4种方法:
事先共享密码:双方加密前通过安全途径交换密钥,但是在数据库中,双方为服务端和磁盘,即密钥和磁盘在同一区域,不安全,所以数据库不会考虑这种方式。
使用公钥密码:由于我们这里使用对称加密体系,所以不考虑公钥。但是这可以作为密钥交换的一部分使用。
使用密钥分配中心:将密钥存储到可信任的第三方,使用时通过第三方获取密钥。在需要使用密钥时,向第三方通讯,生成会话密钥,使用会话密钥加密密钥进行发送密钥。这里的会发密钥可以使用公钥加密体系。
Diffie-Hellman密钥交换:Diffie-Hellman是1976年由Whitfield Diffie和Martin Hellman共同发明的一种算法。该算法可以通过交换可以公开的信息就能够生成共享的秘密数字,从而达到共享密钥的目的,其过程如下图所示:
DB server向Key server(以下简称D和K)发送两个质数P,G;
D生成一个随机数A;
K生成一个随机数B;
D将G^A mod P 发送给K;
K将G^B mod P 发送给D;
D使用K发过来的数B', 计算B’mod P,这就是数据加密密钥;
K使用D发过来的数A',计算A' mod P,这个和D计算得到的加密密钥是相等的。
当然再加入数据库时,同样需要使用安全第三方作为信息交换,但这减少了密钥被窃听的可能性。
4
密钥轮转
密钥轮转,分为密钥更新和作废两部分。 密钥更新,更新可以提高密钥暴力破解的难度,其次即便是过去的密钥被破解也无法获取当前的数据。 密钥作废,在更新后要及时对密钥进行作废,这里的作废不仅仅指的是删除,而是要达到无法还原密钥的目的。