PGCrypto 加密組件使用


PGCrypto 插件提供了兩類加密算法:單向加密和雙向加密。

  • 單向加密屬於不可逆加密,無法根據密文解密出明文,適用於數據的驗證,例如登錄密碼驗證。常用的單向加密算法有 MD5、SHA、HAC 等。這類加密算法能夠保證相同的數據相同的密鑰加密的結果是相同的。
  • 雙向加密屬於可逆加密,根據密文和密鑰可解密出明文,適用於數據的安全傳輸,例如電子支付、數字簽名等。常用的雙向加密算法有 AES、DES、RSA、ECC 等。

kbcrypto 是以 pgcrypto插件為基礎,增加了國密算法的支持。以下以Kingbase kbcrypto 插件為例,演示具體函數的使用。以下例子,除了 rc4 和 sm4 函數外,所有的例子都同時在 PG12.3 和 KINGBASE V8R6 進行過驗證。

一、kbcrypto 包含的函數

test=# \dx+ kbcrypto
            Objects in extension "kbcrypto"
                  Object description                   
-------------------------------------------------------
 function armor(bytea)
 function armor(bytea,text[],text[])
 function crypt(text,text)
 function dearmor(text)
 function decrypt(bytea,bytea,text)
 function decrypt_iv(bytea,bytea,bytea,text)
 function digest(bytea,text)
 function digest(text,text)
 function encrypt(bytea,bytea,text)
 function encrypt_iv(bytea,bytea,bytea,text)
 function gen_random_bytes(integer)
 function gen_random_uuid()
 function gen_salt(text)
 function gen_salt(text,integer)
 function hmac(bytea,bytea,text)
 function hmac(text,text,text)
 function pgp_armor_headers(text)
 function pgp_key_id(bytea)
 function pgp_pub_decrypt(bytea,bytea)
 function pgp_pub_decrypt_bytea(bytea,bytea)
 function pgp_pub_decrypt_bytea(bytea,bytea,text)
 function pgp_pub_decrypt_bytea(bytea,bytea,text,text)
 function pgp_pub_decrypt(bytea,bytea,text)
 function pgp_pub_decrypt(bytea,bytea,text,text)
 function pgp_pub_encrypt_bytea(bytea,bytea)
 function pgp_pub_encrypt_bytea(bytea,bytea,text)
 function pgp_pub_encrypt(text,bytea)
 function pgp_pub_encrypt(text,bytea,text)
 function pgp_sym_decrypt_bytea(bytea,text)
 function pgp_sym_decrypt_bytea(bytea,text,text)
 function pgp_sym_decrypt(bytea,text)
 function pgp_sym_decrypt(bytea,text,text)
 function pgp_sym_encrypt_bytea(bytea,text)
 function pgp_sym_encrypt_bytea(bytea,text,text)
 function pgp_sym_encrypt(text,text)
 function pgp_sym_encrypt(text,text,text)
 function rc4(bytea,bytea,integer)
 function sm4(bytea,bytea,integer)
 function sm4_ex(bytea,bytea,integer,integer)
(39 rows)

相比於 pgcrypto , KINGBASE kbcrypto 增加了 rc4 與國密算法支持sm4 , sm4_ex 

二、單向加密

1、digest

digest() 函數可以根據不同的算法進行加密,沒有密鑰。相同的數據加密的結果相同。語法如下:

digest(data text, type text) returns bytea
digest(data bytea, type text) returns bytea

其中,data 是原始數據;type 是加密算法,包括 md5、sha1、sha224、sha256、sha384 以及 sha512;函數的返回結果為二進制字符串。

test=# select encode(digest('abc','sha256'),'hex');
encode
------------------------------------------------------------------
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

其中,encode 函數用於將二進制字符串轉換為十六進制的文本。

2、hmac

與digest 不同,hmac 支持加密密鑰。相同數據、相同密鑰加密結果相同。語法如下:

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

其中,data 是原始數據;key 是加密密鑰;type 是加密算法,包括 md5、sha1、sha224、sha256、sha384 以及 sha512;

test=# select encode(hmac('abc','keyvalue','sha256'),'hex');
                              encode                              
------------------------------------------------------------------
 d0ba06791b5e37aa5ccb28535a5894d82ce39c5401ef4486211e2e6b553b9d3d

3、crypt

crypt() 和 gen_salt() 函數專用於密碼加密,其中 crypt() 用於加密數據,gen_salt() 用於生成 salt(加鹽)。對於相同的密碼,crypt() 函數每次也會返回不同的結果,因為 gen_salt() 函數每次都會生成不同的 salt。語法如下:

crypt(password text, salt text) returns text
gen_salt(type text [, iter_count integer ]) returns text

gen_salt() 函數每次都會生成一個隨機的鹽值字符串,該字符串同時決定了 crypt() 函數使用的算法;type 參數用於指定一個生成字符串的哈希算法,可能的取值包括 des、xdes、md5 以及 bf。

test=# select crypt('abc',gen_salt('md5'));
               crypt                
------------------------------------
 $1$NFHmXmm7$rwLqQ24kN3IkLyHzs.UrC1
(1 row)

test=# select crypt('abc','$1$NFHmXmm7$rwLqQ24kN3IkLyHzs.UrC1');
               crypt                
------------------------------------
 $1$NFHmXmm7$rwLqQ24kN3IkLyHzs.UrC1
(1 row)

test=# select crypt('abcd','$1$NFHmXmm7$rwLqQ24kN3IkLyHzs.UrC1');
               crypt                
------------------------------------
 $1$NFHmXmm7$nkmVGJH7Sci5EqoIYUuma0
(1 row)

gen_salt() 每次都會生成不同的值,要驗證密碼的准確性,只要將原加密結果做為salt。實際應用常見的驗證密碼是否正確的方式:password = crypt('abc', password);

 二、雙向加密

PGP 加密函數實現了 OpenPGP(RFC 4880)標准中的加密功能,包括對稱密鑰加密(私鑰加密)和非對稱密鑰加密(公鑰加密)。

1、對稱密鑰加密

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_decrypt(msg bytea, psw text [, options text ]) returns text
pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea

其中,data 是要加密的數據;psw 是 PGP 對稱密鑰;options 設置選項

使用例子:

test=# select pgp_sym_encrypt('abc','key_value');
                                                               pgp_sym_encrypt                                                                
----------------------------------------------------------------------------------------------------------------------------------------------
 \xc30d04070302f93fbd59b40bf7fd71d2340175c19d234d275f5b8ae668fecbbdfd80f0e94185f07dee15cb6d2b0dfbfdf08c98648e07da8f3d8902bb3dd349fdb36860a1ff
(1 row)

test=# select pgp_sym_decrypt(pgp_sym_encrypt('abc','key_value'),'key_value');              
 pgp_sym_decrypt 
-----------------
 abc
(1 row)

options 使用:

pgp_sym_encrypt(data, password, 'compress-algo=1, cipher-algo=aes256')

常用的option有:

cipher-algo,使用的密碼算法,可以是 bf、aes128(默認值)、aes192、aes256;
compress-algo,使用的壓縮算法,只有編譯 PostgreSQL 時使用了 zlib 參數可用。可以是:0,不壓縮,默認值;1,ZIP 壓縮;2,ZLIB 壓縮(ZIP 加上元數據和 CRC)

2、非對稱公鑰加密

具體見:https://www.cnblogs.com/kingbase/p/14814842.html

3、其他雙向加解密函數

具體函數:

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

rc4(bytea,bytea,integer)

其中,data 是需要加密的數據;type 用於指定加密方法。 algorithm 的可能取值如下:

  • bf,Blowfish 算法
  • aes,AES 算法(Rijndael-128、-192 或者-256)

具體例子如下:

test=# select encrypt('abc','key1','bf');
      ENCRYPT       
--------------------
 \xa071d8f60a60180a
(1 row)

test=# select decrypt('\xa071d8f60a60180a','key1','bf');
 DECRYPT  
----------
 \x616263
(1 row)

test=# select encode(decrypt('\xa071d8f60a60180a','key1','bf'),'escape');
 ENCODE 
--------
 abc
(1 row)

不同於DES的是,RC4不是對明文進行分組處理,而是字節流的方式依次加密明文中的每一個字節,解密的時候也是依次對密文中的每一個字節進行解密。

test=# select rc4('abc','key1',0);   --0, 表示加密
   RC4    
----------
 \x05b062
(1 row)

test=# select rc4(rc4('abc','key1',0),'key1',1);    --1,表示解密
   RC4    
----------
 \x616263
(1 row)

test=# select encode(rc4(rc4('abc','key1',0),'key1',1),'escape');
 ENCODE 
--------
 abc
(1 row)

三、國密算法支持

SM4算法是一種分組密碼算法,其分組長度為128bit,密鑰長度也為128bit,長度不夠補 0x00。

test=# select sm4('abc','key1',0);      --0 , 加密                         
                SM4                 
------------------------------------
 \x875fdc780aa92500b8c0b17ed82e9ab9
(1 row)

test=# select sm4(sm4('abc','key1',0),'key1',1);     --1 , 解密
   SM4    
----------
 \x616263
(1 row)

test=# select encode(sm4(sm4('abc','key1',0),'key1',1),'escape');
 ENCODE 
--------
 abc
(1 row)

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM