AnalyticDB for PostgreSQL內建加密解密模組pgcryoto並整合國密SM4密碼編譯演算法,允許資料庫使用者以加密形式儲存資料的某些列,為敏感性資料增加了一層額外的保護。無密鑰時,任何使用者都無法讀取以加密形式儲存在資料庫中的資料。
注意事項
pgcrypto外掛程式在資料庫伺服器內部運行,所有資料和密碼都以明文形式在資料庫和用戶端應用程式之間傳輸。為了獲得最佳安全性,建議在用戶端和AnalyticDB for PostgreSQL之間使用SSL串連。
安裝pgcrypto外掛程式
使用pgcryoto外掛程式之前,請您在AnalyticDB for PostgreSQL執行個體外掛程式管理中安裝pgcrypto外掛程式。具體操作,請參見安裝、升級與卸載外掛程式。
通用雜湊函數
digest()函數可以根據不同的演算法產生資料的二進位雜湊值。
文法
digest(data text, type text) returns bytea
digest(data bytea, type text) returns byteadata:需要計算二進位雜湊值的未經處理資料。type:密碼編譯演算法。包括MD5、SHA1、SHA224、SHA256、SHA384和SHA512。
樣本
使用digest()函數對字串ADBPG進行sha256加密儲存,樣本如下。
SELECT digest('ADBPG','sha256');返回結果如下。
digest
--------------------------------------------------------------------
\x2d0525fa98e83619424dc1303ba107c59aabb389bbe94ceef885c742088560bc
(1 row)密碼雜湊函數
crypt()和gen_salt()函數專用於雜湊密碼。crypt()執行雜湊用於加密資料,gen_salt()用於產生加鹽雜湊。
crypt()函數中的演算法和普通的MD5或者SHA1雜湊演算法存在以下不同之處:
crypt()函數中演算法很慢。密碼通常長度較小,crypt()只能用比較複雜的密碼編譯演算法來增加破解難度。crypt()函數使用一個隨機值(Salt,即鹽值),使得具有相同口令的使用者將得到不同的密文口令。這也是針對破解演算法提供一種額外的安全保護。crypt()函數的結果中包括了演算法類型,因此可以針對不同使用者使用不同的演算法對密碼進行加密。crypt()函數的一些演算法具有自適應性,意味著當電腦效能變得更快時,可以調整該演算法使其變得更慢,而不會產生與已有密碼的不相容性。
crypt()函數支援的演算法
演算法 | 密碼最大長度 | 是否自適應 | Salt 位元 | 輸出長度 | 描述 |
BF | 72 | 是 | 128 | 60 | 基於Blowfish的變體2a演算法。 |
MD5 | unlimited | 否 | 48 | 34 | 基於MD5的密碼編譯演算法。 |
XDES | 8 | 是 | 24 | 20 | 擴充DES。 |
DES | 8 | 否 | 12 | 13 | 原生UNIX加密。 |
crypt()文法
crypt(password text, salt text) returns text crypt()函數返回password字串的雜湊值,salt參數由gen_salt()函數產生。由於gen_salt()函數每次都會產生不同的salt,因此對於相同的password字串,crypt()函數每次也會返回不同的結果。校正密碼時可以將之前產生的雜湊結果作為salt。
crypt()樣本
樣本一:通過
crypt()函數設定一個新密碼。UPDATE ... SET pswhash = crypt('my_password', gen_salt('md5'));樣本二:通過比較儲存的密碼雜湊值驗證輸入的密碼的正確性。
SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;如果輸入的口令正確,會返回true。
gen_salt()文法
gen_salt(type text [, iter_count integer ]) returns text gen_salt()函數用來產生隨機的參數輸入給crypt,此函數每次都會產生一個隨機的鹽值(salt)字串,該字串同時決定了crypt()函數使用的演算法。
type:用於指定一個產生字串的雜湊演算法,取值包括DES、XDES、MD5及BF。
iter_count:對於XDES和BF演算法,iter_count指定迭代次數,數字越大加密時間越長,被破解需要的時間也越長。
gen_salt()樣本
SELECT gen_salt('des'), gen_salt('xdes'), gen_salt('md5'), gen_salt('bf');返回結果如下。
gen_salt | gen_salt | gen_salt | gen_salt
----------+-----------+-------------+-------------------------------
qh | _J9..uEUi | $1$SNgqyKAi | $2a$06$B/Etc3J8zYBV49LrDU97MO
(1 row)PGP加密函數
AnalyticDB for PostgreSQL實現了OpenPGP(RFC 4880)標準,支援對稱式加密和非對稱式加密。
pgp_sym_encrypt()
pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea pgp_sym_encrypt()用於對稱金鑰密碼編譯。
data:需要加密的資料。psw:PGP對稱金鑰。options:用於設定選項。
pgp_sym_decrypt()
pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea pgp_sym_decrypt()用於解密PGP對稱金鑰密碼編譯後的訊息。
msg:需要解密的訊息。psw:PGP對稱金鑰。options:用於設定選項。
為了避免輸出無效的字元,不允許使用pgp_sym_decrypt函數對Bytea資料進行解密,可以使用 pgp_sym_decrypt_bytea對原始文本資料進行解密。
pgp_pub_encrypt()
pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea pgp_pub_encrypt()用於公開金鑰祕密金鑰加密。
data:需要加密的資料。key:PGP公開金鑰,如果傳入一個私密金鑰將會返回錯誤。options:用於設定選項。
pgp_pub_decrypt()
pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text
pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea pgp_pub_decrypt()用於解密一個公用祕密金鑰加密的訊息。
msg:需要解密的訊息。key:必須是用於加密的公開金鑰的私密金鑰。如果私密金鑰是用口令保護的,必須在psw中給出該口令。如果沒有口令,但想要指定選項,需要給出一個空口令。
為了避免輸出無效的字元,不允許使用pgp_pub_decrypt函數對Bytea資料進行解密,可以使用pgp_pub_decrypt_bytea對原始文本資料進行解密。key為公用金鑰組應的私密金鑰,如果私密金鑰使用了密碼保護功能,必須在psw參數中指定密碼;如果沒有使用密碼保護,想要指定options參數時必須指定一個空的psw。
隨機資料函數
gen_random_bytes()
gen_random_bytes(count integer) returns bytea gen_random_bytes()函數用於產生具有強加密性的隨機位元組。
count:返回的位元組數,取值為1~1024。
樣本:
SELECT gen_random_bytes(16);返回結果如下。
gen_random_bytes
------------------------------------
\x1f1eddc11153afdde0f9e1229f8f4caf
(1 row)gen_random_uuid()
gen_random_uuid()函數用於返回一個Version 4的隨機UUID。
樣本:
SELECT gen_random_uuid();返回結果如下。
gen_random_uuid
--------------------------------------
2bd664a2-b760-4859-8af6-8d09ccc5b830國密SM4密碼編譯演算法
根據資訊安全的相關要求,敏感資訊通常需要在資料庫中進行加密儲存,例如登入密碼、信用卡號、社會安全號碼等。pgcrypto外掛程式提供了多種密碼編譯演算法,總體上分為單向加密和雙向加密:
單向加密:屬於無法復原加密,無法根據密文解密出明文,適用於資料的驗證,例如登入密碼驗證。
雙向加密:屬於可逆加密,根據密文和密鑰可解密出明文,適用於資料的安全傳輸,例如電子支付、數位簽章等。
AnalyticDB for PostgreSQL還支援國密演算法SM4。SM4屬於雙向加密,您需要提供密鑰,在資料庫服務端進行加密。
SM4演算法目前只支援Text和Varchar資料類型,應用開發人員需要在業務側將待加密的資料轉成字串(String)後,再進行加密。
僅支援V6.3.8.9及以上版本,安裝或升級外掛程式需要如何查看執行個體核心版本,請參見查看核心小版本。
安裝
使用國密演算法SM4之前,您需要在AnalyticDB for PostgreSQL執行個體外掛程式管理中安裝pgcrypto外掛程式。具體操作,請參見安裝、升級與卸載外掛程式。
加密
使用SM4函數加密關鍵字段文法如下。
-- 加密text格式資料
sm4_encrypt_text(<data text>, <password text>)
-- 加密varchar格式資料
sm4_encrypt_varchar(<data varchar>, <password text>)參數說明如下。
參數 | 說明 |
| 需要加密的Text格式的資料。 |
| 需要加密的Varchar格式的資料。 |
| 加密金鑰,為Text格式。 |
樣本一:對文字欄位
who am i進行加密,密鑰為key,樣本如下。SELECT sm4_encrypt_text('who am i','key');加密後的值為Bytea類型,返回資訊如下。
sm4_encrypt_text ------------------------------------ \x308b71cc7fa0de7d720b2c394a3a83c2 (1 row)樣本二:使用SM4加密函數將明文資料轉成密文資料後,寫入密文表。建立表
t_plain儲存明文資料和表t_enc儲存密文資料。-- DROP EXTENSION encdb; CREATE TABLE t_plain( id int, name varchar(20), introduction text ) distributed BY (id); INSERT INTO t_plain VALUES (1, 11, 'aaa'); CREATE TABLE t_enc( id int, name varchar(20), introduction bytea ) distributed by (id); INSERT INTO t_enc SELECT id ,name, sm4_encrypt_text(introduction,'passwd') FROM t_plain; SELECT * FROM t_enc;introduction欄位的值已被加密,返回資訊如下。
id | name | introduction ----+------+------------------------------------ 1 | 11 | \x0ca8e6c45a83e98efe99dcde0510930e (1 row)
解密
使用SM4函數查詢加密欄位文法如下。
-- 解密text格式資料
sm4_decrypt_text(data bytea, password text)
-- 解密varchar格式資料
sm4_decrypt_varchar(data bytea, password text)參數說明如下。
參數 | 說明 |
| 需要解密的Bytea類型的資料。 |
| 加密金鑰,為Text格式。 |
樣本一:對上文加密的欄位進行解密,樣本如下。
SELECT sm4_decrypt_text('\x308b71cc7fa0de7d720b2c394a3a83c2'::bytea, 'key');解密的內容為
who am i,返回資訊如下。sm4_decrypt_text ------------------ who am i (1 row)樣本二:使用SM4函數解密查詢密文表
t_enc。SELECT id, name, sm4_decrypt_text(introduction,'passwd') FROM t_enc;introduction欄位的值已解密,返回資訊如下。
id | name | sm4_decrypt_text ----+------+------------------ 1 | 11 | aaa (1 row)
相關文檔
pgcrypto的詳細資料,請參見postgresql。