pgcrypto
功能描述
pgcrypto模块允许数据库用户以加密形式存储数据的某些列。在没有密钥的情况下,任何用户都无法读取以加密形式存储在数据库中的数据。
创建pgcrypto插件:
CREATE EXTENSION pgcrypto;
注意事项
所有pgcrypto函数都在数据库服务器内部运行,所有数据和密码都以明文形式在数据库和客户端应用程序之间传输。为了获得最佳安全性,建议在客户端与Vastbase之间使用SSL连接。
如果函数的任一参数是NULL,那么所有函数都返回NULL。这种情况可能会造成安全风险。
pgcrypto支持的密码函数
通用哈希函数
digest
功能描述
digest()
函数可以根据不同的算法生成数据的二进制哈希值。
语法格式
digest(data text, type text) returns bytea
digest(data bytea, type text) returns bytea
参数说明
data:需要计算二进制哈希值的原始数据。
type:加密算法。包括MD5、SHA1、SHA224、SHA256、SHA384和SHA512。
示例
使用digest()
函数对字符串进行md5加密存储:
SELECT digest('Vastbase','md5');
返回结果如下:
digest
------------------------------------
\x2619c3dc06e4f47ec8063265ea5eb151
(1 row)
hmac
功能描述
为带有键key的数据计算散列的MAC。
语法格式
hmac(data text, key text, type text) returns bytea
hmac(data bytea, key bytea, type text) returns bytea
参数说明
- data:需要计算MAC值的原始数据。
- key:数据对应的键。
- type:加密算法。包括MD5、SHA1、SHA224、SHA256、SHA384和SHA512。
示例
select hmac('ABC','key1','SHA256');
返回结果如下:
hmac
--------------------------------------------------------------------
\xd34d136e372563353669c3eb1333bf9d88dbcc488e71606a9007807fc97d140d
(1 row)
密码哈希函数
crypt
功能描述
crypt()
函数返回password字符串的哈希值。
crypt()
函数使用一个随机盐值(由gen_salt()
函数生成),使得具有相同口令的用户将得到不同的密文口令。由于gen_salt()函数每次都会生成不同的salt,因此对于相同的password字符串,crypt()函数每次也会返回不同的结果。校验密码时可以将之前生成的哈希结果作为salt。函数的结果中包括了算法类型,因此可以针对不同用户使用不同的算法对密码进行加密。
表1 crypt()函数支持的算法
算法 | 密码最大长度 | 是否自适应 | Salt 位数 | 输出长度 | 描述 |
---|---|---|---|---|---|
BF | 72 | 是 | 128 | 60 | 基于Blowfish的变体2a算法。 |
MD5 | unlimited | 否 | 48 | 34 | 基于MD5的加密算法。 |
XDES | 8 | 是 | 24 | 20 | 扩展的DES。 |
DES | 8 | 否 | 12 | 13 | 原生UNIX加密。 |
语法格式
crypt(password text, salt text) returns text
示例
SELECT crypt('password@123', gen_salt('des'));
返回结果如下(随机):
crypt
---------------
BSkfNxImwPHeQ
(1 row)
gen_salt
功能描述
gen_salt()
函数用来产生随机的参数输入给crypt,此函数每次都会生成一个随机的盐值(salt)字符串,该字符串同时决定了crypt()函数使用的算法。
语法格式
gen_salt(type text [, iter_count integer ]) returns text
参数说明
type:用于指定一个生成字符串的哈希算法,取值包括DES、XDES、MD5及BF。
iter_count:对于XDES和BF算法,iter_count指定迭代次数,数字越大加密时间越长,被破解需要的时间也越长。
示例
SELECT gen_salt('des'), gen_salt('xdes'), gen_salt('md5'), gen_salt('bf');
返回结果如下(随机):
gen_salt | gen_salt | gen_salt | gen_salt
----------+-----------+-------------+-------------------------------
cC | _J9..Ta32 | $1$zQ9Vp0r5 | $2a$06$dFp.gUCjMZq3iKzfc.DHye
(1 row)
PGP加密函数
该功能实现了部分OpenPGP (RFC 4880)标准的加密。支持对称秘钥和公共秘钥的加密。
一个加密的 PGP 消息由两个部分(或包)组成:
数据包包含一个会话秘钥:加密了的对称秘钥或公共秘钥。
数据包包含带有会话秘钥的加密数据。
使用 GnuPG 生成 PGP 密钥的方法请参考GnuPG上的文档。
pgp_sym_encrypt
功能描述
使用一个对称 PGP 密钥对数据进行加密。
语法格式
pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
参数说明
- data:需要加密的数据。
- psw:PGP对称密钥。
- options:用于设置选项。options可能的取值请参考PGP 函数选项。
示例
select pgp_sym_encrypt('ABCD','psw1');
返回结果如下:
pgp_sym_encrypt('ABCD','psw1')
------------------------------------------------------------------------------------------------------------------------------------------------
\xc30d04070302be8fd6abd0c68f6b64d235014f5618979157d9a70366fbe679b4ff0cb65e3c31c9c520e56d1fb5b2c3df799b74a8ce6e8482153598921d4df6c5be132dc72774
(1 row)
pgp_sym_decrypt
功能描述
解密一个用对称密钥加密过的 PGP 消息。
为了避免输出非法的字符数据,请勿使用pgp_sym_decrypt直接解密bytea数据。
语法格式
pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
参数说明
- msg:需要解密的消息。
- psw:PGP对称密钥。
- options:用于设置选项。options可能的取值请参考PGP 函数选项。
示例
select pgp_sym_decrypt(pgp_sym_encrypt('ABCD','psw1'),'psw1');
返回结果如下:
pgp_sym_decrypt
-----------------
ABCD
(1 row)
pgp_pub_encrypt
功能描述
使用 PGP 公钥对数据进行加密。
语法格式
pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
参数说明
- data:需要加密的数据。
- key:PGP公钥,如果传入一个私钥将会返回错误。
- options:用于设置选项。options可能的取值请参考PGP 函数选项。
pgp_pub_decrypt
功能描述
解密一个公共密钥加密的消息。key必须是对应于用来加密的公钥的私钥。如果私钥是用口令保护的,则必须在psw中给出该口令。如果没有口令,但想要指定选项,此时可以指定一个空口令。
为了避免输出非法的字符数据,请勿使用pgp_pub_decrypt直接解密bytea数据。
语法格式
pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text
参数说明
- msg:需要解密的消息。
- key:必须是用于加密的公钥的私钥。如果私钥是用口令保护的,必须在psw中给出该口令。如果没有口令,但想要指定选项,此时可以指定一个空口令。
- options:用于设置选项。options可能的取值请参考PGP 函数选项。
PGP 函数的选项
options(后文称为“选项”)被命名为与 GnuPG 类似的形式。一个选项的值应该在一个等号后给出,各个选项之间用逗号分隔。例如:
pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')
除convert-crlf以外的所有选项只适用于加密函数。解密函数会从 PGP 数据中得到这些参数。
cipher-algo
要用哪个密码算法。
值:bf,aes128,aes192,aes256 (只用于 OpenSSL:3des,cast5)
默认:aes128
适用于:pgp_sym_encrypt,pgp_pub_encrypt
compress-algo
要使用哪种压缩算法。只有PostgreSQL编译时使用了 zlib 时才可用。
值:
- 0:不压缩
- 1:ZIP 压缩
- 2:ZLIB 压缩 (ZIP 外加元数据和块 CRC)
默认:0
适用于:pgp_sym_encrypt, pgp_pub_encrypt
compress-level
压缩多少。级别越高压缩得越小但是速度也越慢。0 表示禁用压缩。
值:0~9
默认:6
适用于:pgp_sym_encrypt, pgp_pub_encrypt
convert-crlf
加密时是否把\n转换成\r\n以及解密时是否把\r\n转换成\n。RFC 4880 指定文本数据存储时应该使用\r\n换行。使用这个选项能够得到完全 RFC 兼容的行为。
值:0,1
默认:0
适用于:pgp_sym_encrypt,pgp_pub_encrypt,pgp_sym_decrypt,pgp_pub_decrypt
disable-mdc
不用 SHA-1 保护数据。使用此选项是为了兼容旧版 PGP 产品,这些产品在受 SHA-1 保护的包被加入到 RFC 4880 之前就已经存在了。gnupg.org 和 pgp.com 软件都支持此功能。
值:0,1
默认:0
适用于:pgp_sym_encrypt, pgp_pub_encrypt
sess-key
使用单独的会话密钥。公钥加密总是使用一个单独的会话密钥。此选项用于对称密钥,对称密钥加密时默认使用 S2K 密钥。
值:0,1
默认:0
适用于:pgp_sym_encrypt
s2k-mode
要使用哪一种 S2K 算法。
值:
- 0:不使用 salt。(不建议这样使用。)
- 1:使用 salt,使用固定的迭代数。
- 3:可变的迭代数。
默认:3
适用于:pgp_sym_encrypt
s2k-count
S2K 算法要使用的迭代次数。取值在1024 ~ 65011712 之间,包括首尾两个值在内。
默认:65536 和 253952 之间的一个随机值。
适用于:pgp_sym_encrypt,只能用于
s2k-mode=3
。s2k-digest-algo
要在 S2K 计算中使用哪种摘要算法。
值:md5,sha1
默认:sha1
适用于:pgp_sym_encrypt
s2k-cipher-algo
要用哪种密码来加密独立的会话密钥。
值:bf,aes,aes128,aes192,aes256
默认:use cipher-algo
适用于:pgp_sym_encrypt
unicode-mode
是否把文本数据在数据库内部编码和 UTF-8 之间来回转换。如果数据库已经是 UTF-8,将不会转换,但是消息将被标记为 UTF-8。没有这个选项它将不会被标记。
值:0,1
默认:0
适用于:pgp_sym_encrypt,pgp_pub_encrypt
pgp_key_id
功能描述
pgp_key_id抽取一个 PGP 公钥或私钥的密钥 ID。或者如果给定了一个加密过的消息,它给出一个用来加密数据的密钥 ID。
它能够返回 2 个特殊密钥 ID:
SYMKEY:该消息是用一个对称密钥加密的。
ANYKEY:该消息是用公钥加密的,但是密钥 ID 已经被移除。这意味着将要尝试所有的密钥来确认哪个能解密该消息。pgcrypto本身不产生这样的消息。
注意不同的密钥可能具有相同的 ID。这很少见但正常的现象。客户端应用需要尝试用每一个去解密,像处理ANYKEY一样。
语法格式
pgp_key_id(bytea) returns text
armor、dearmor
功能描述
这些函数将二进制数据封装/解包为PGP ASCII-Armor格式,该格式基本上是具有CRC和其他格式的BASE64。
如果指定了keys和值数组values,每一个键值对的 armored 格式上会增加一个armor header。两个数组都必须是一维数组,并且它们的长度必须相同。键和值不能包含任何非 ASCII 字符。
语法格式
armor(data bytea) returns text
dearmor(data text) returns bytea
参数说明
data:输入的二进制数据。
随机数据函数
gen_random_bytes
功能描述
gen_random_bytes函数返回count个具有强加密性的随机字节。
语法格式
gen_random_bytes(count integer) returns bytea
参数说明
count:返回的字节数,取值为1~1024。
示例
SELECT gen_random_bytes(16);
随机结果如下:
gen_random_bytes
------------------------------------
\xcda7c6b4c151c682e31154b8610d49e2
(1 row)