美文网首页
postgre自带的pgrypto之encrypt和decryp

postgre自带的pgrypto之encrypt和decryp

作者: 洪兴掌管一代 | 来源:发表于2021-10-31 12:21 被阅读0次

pgcrypto 提供了两类加密算法:单向加密和双向加密。

单向加密属于不可逆加密,无法根据密文解密出明文,适用于数据的验证,例如登录密码验证。常用的单向加密算法有 MD5、SHA、HMAC 等。双向加密属于可逆加密,根据密文和密钥可解密出明文,适用于数据的安全传输,例如电子支付、数字签名等。常用的双向加密算法有 AES、DES、RSA、ECC 等。


本文主要演示使用原始加密函数encrypt和decrypt函数做基于AES算法的双向加密过程。

首先来一波技术概念介绍。部分概念出自:https://blog.csdn.net/horses/article/details/109073000

原始加密函数仅仅会对数据进行一次加密,不支持 PGP 加密的任何高级功能,因此存在以下主要问题:

    直接将用户密钥作为加密密钥。

    不提供任何完整性检查校验加密后的数据是否被修改。

    需要用户自己关联所有的加密参数,包括初始值(IV)。

    不支持文本数据。

    因此,在引入了 PGP 加密之后,不建议使用这些原始加密函数(后续会发布pgp加密使用教程):

    encrypt(data bytea,key bytea,type text) returns bytea 

    decrypt(data bytea,key bytea,type text) returns bytea 

    encrypt_iv(data bytea,key bytea,iv bytea,type text) returns bytea 

    decrypt_iv(data bytea,key bytea,iv bytea,type text) returns bytea

其中,data 是需要加密的数据;type 用于指定加密方法。type 参数的语法如下:

algorithm[- mode][/pad: padding]

其中 algorithm 的可能取值如下:bf,Blowfish 算法,aes,AES 算法(Rijndael-128、-192 或者-256)

mode 的可能取值如下:cbc,下一个块依赖于前一个块(默认值)ecb,每个块独立加密(仅用于测试)

padding 的可能取值如下:pkcs,数据可以是任意长度(默认值);none,数据长度必须是密码块大小的倍数

例如,以下函数的加密结果相同:

encrypt(data,'fooz','bf');encrypt(data,'fooz','bf-cbc/pad:pkcs')

对于函数 encrypt_iv 和 decrypt_iv,参数 iv 表示 CBC模式的初始值,ECB 模式忽略该参数。如果它的长度不是准确的块大小,可能会被截断或者使用 0 进行填充。对于没有该参数的两个函数,默认全部使用 0 填充。


接下来演示使用过程。技术栈springboot mybatis。

1.安装pgcrypto 模块

对于 Windows 和 macOS,默认安装已经包含了扩展模块。我们只需要执行以下语句在当前数据库中安装 pgcrypto 模块:

CREATE EXTENSION pgcrypto;

此后,便可使用encrypt函数和decrypt函数。

2.mybatis的xml文件中insert语句中做字段加密

<insert id="insertUserInfo" keyProperty="userId" parameterType="UserInfo"

        useGeneratedKeys="true">

insert into travel_fly.user_info

(username,password,create_time,last_update_time,domain_username)

values(

#{username,jdbcType=VARCHAR},

Here we use domain username as secret key.

Aes is the encryption algorithm. -->

 encrypt(#{password,jdbcType=VARCHAR}::bytea,#{domainUsername}::bytea,'aes'),

current_timestamp,

current_timestamp,

#{domainUsername,jdbcType=VARCHAR}

)

</insert>

3. mybatis的xml文件中select语句中做字段解密。

<select id="selectAllUserInfo" resultMap="userInfoModel">

 select user_id,

username,

convert_from(decrypt(password::bytea,domain_username::bytea,'aes'),'SQL_ASCII') password,

create_time,

last_update_time,

domain_username

from travel_fly.user_info

</select>


注意:加密解密函数接受的前两个参数要求是bytea二进制类型,所以使用::bytea做了类型转换。这里使用了当前登录用户的domainUsername字段作为密钥


另外对函数convert_from(string bytea, src_encoding name)做简单说明。

官方文档:Convert string to the database encoding. The original encoding is specified by src_encoding. The string must be valid in this encoding. 转换字符串编码,自己要指定源编码,目标编码默认为数据库指定编码,

例子:select convert_from('\316\322\312\307pmars','GBK'); = "我是pmars"


SQL_ASCII是postgre数据库的默认编码格式。


注意:发现以上在select和insert块中的加粗的加密解密语句,在postgre版本13下报错,无法识别为函数,但是版本14就好用了。

相关文章

网友评论

      本文标题:postgre自带的pgrypto之encrypt和decryp

      本文链接:https://www.haomeiwen.com/subject/zproaltx.html