.pgpass文件用于保存用户密码,方便客户端连接登录数据库。
psql(libpq.so)为什么不在命令行通过参数指定密码呢?因为这样传递密码可以在ps命令中看到明文密码,密码会被暴漏给其他用户。
.pgpass文件存储密码的格式如下:
hostname:port:database:username:password
类似于pg_hba.conf文件,逐字段匹配,当前面hostname、port、database、username都匹配成功后,那么就使用该条目的password进行连接。
在.pgpass文件中,密码是明文保存的,也有被泄露的风险,所以考虑加密处理。
加密密钥:
1、首先考虑固定密钥加密,编写工具软件,使用固定密钥加密pgpass文件中的所有password,psql(准确的说是libpq.so库)使用同样的固定密钥解密password;
2、使用固定密钥加密好像并不能保护密码,因为别人虽然看不到密码明文是什么,但别人把加密后的.pgpass拿走一样可以使用。所以增加自定义加密密码,工具软件增加一个参数指定一个自定义密码和固定密钥一起做种子生成加密密钥,这样别人拿走.pgpass文件也用不了了;
3、考虑集群安装,可能一个集群中若干台设备都是批量自动安装,为使自动化安装方便又能保证各集群的加密密钥不一样,考虑把pg_control文件中的数据库ID做密钥种子的一部分用于加密密钥生成,这样各个集群的加密密钥也就不可能一样了;
4、如果不想每一台设备上都手动输入不一样的自定义密码、又想各个设备间的密钥不一样,考虑增加MAC地址做密钥种子的一部分。
这样密钥派生方式可以通过固定密码以及可选的ID、MAC、自定义密码做种子进行派生。
加密:
1、.pgpass文件中如果有多条数据,其中有两条的password完全相同,那么加密后的密文也完全相同,也可能暴漏一些信息,考虑使用CBC模式的对称加密算法,每一个password都通过随机数生成IV保存到Password密文前面,解密时使用该IV解密;
2、如果想要.pgpass文件中的password有的加密有的不被加密,让psql可以自动识别:加密的解密后使用,没加密的直接使用。考虑在密文后面增加hash值,检查前面的IV和中间的密文的hash值和后面的保存的hash值是否一致,如果没有hash值或者不一致则肯定是没有加密的。
这样处理后的密文组成是这样的:IV||E(password)||HASH
增加这么多处理步骤好像解决了很多问题,但好像也没多大意义。。。
有好的建议欢迎留言,谢谢!
如果有人想要在此基础上设计自己的加密方案并用于专利申请,请联系我删除文章!