資料庫PGP加密演算法、mode、PAD的選擇-PG與Oracle,MySQL的差異(安全性)
標籤
PostgreSQL , Greenplum , crypt , pgcrypt , mode , padding , 演算法 , aes , bf , cbc , ecb , openssl , enc , linux
背景
PostgreSQL, Greenplum的資料加密外掛pgcrypto,用於加密資料。
其中用於PGP對稱加密的函式例子:
Introduction of PGP encryption, usage of raw encryption functions is discouraged.
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
Encrypt/decrypt data using the cipher method specified by type.
The syntax of the type string is:
algorithm [ - mode ] [ /pad: padding ]
where algorithm is one of:
bf — Blowfish
aes — AES (Rijndael-128)
and mode is one of:
cbc — next block depends on previous (default)
ecb — each block is encrypted separately (for testing only)
and padding is one of:
pkcs — data may be any length (default)
none — data must be multiple of cipher block size
So, for example, these are equivalent:
encrypt(data, `fooz`, `bf`)
encrypt(data, `fooz`, `bf-cbc/pad:pkcs`)
In encrypt_iv and decrypt_iv, the iv parameter is the initial value for the CBC mode;
it is ignored for ECB.
It is clipped or padded with zeroes if not exactly block size.
It defaults to all zeroes in the functions without this parameter.
注意,在實際使用時,通常不需要寫mode和pad方法。這樣就帶來了一定的差異。
例如Oracle, MySQL預設的mode是ecb,並不安全。
PostgreSQL預設的mode是cbc,更加安全。
AES
aes是基於資料塊的加密方式,也就是說,每次處理的資料時一塊(16位元組),當資料不是16位元組的倍數時填充,這就是所謂的分組密碼(區別於基於位元位的流密碼),16位元組是分組長度
分組加密的幾種模式:
ECB:是一種基礎的加密方式,密文被分割成分組長度相等的塊(不足補齊),然後單獨一個個加密,一個個輸出組成密文。
CBC:是一種迴圈模式,前一個分組的密文和當前分組的明文異或或操作後再加密,這樣做的目的是增強破解難度。這是PostgreSQL pgcrypto的預設MODE。
CFB/OFB:實際上是一種反饋模式,目的也是增強破解的難度。
FCB和CBC的加密結果是不一樣的,兩者的模式不同,而且CBC會在第一個密碼塊運算時加入一個初始化向量。
mode不一樣導致加密結果不一樣的例子
選擇不一樣的mode,對同一串字元加密,得到的加密結果是不一樣的
1、mode=cbc
postgres=# SELECT UPPER(ENCODE(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes`::text),`hex`))::text ;
upper
------------------------------------------------------------------
BE298AD86D3ADA917C5831A1EA7C856761B0FA22F618928BA56FC4D1C972E402
(1 row)
postgres=# SELECT UPPER(ENCODE(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes-cbc`::text),`hex`))::text ;
upper
------------------------------------------------------------------
BE298AD86D3ADA917C5831A1EA7C856761B0FA22F618928BA56FC4D1C972E402
(1 row)
2、mode=ecb
postgres=# SELECT UPPER(ENCODE(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes-ecb`::text),`hex`))::text ;
upper
------------------------------------------------------------------
BE298AD86D3ADA917C5831A1EA7C8567EB01669E109F443A90D7EEABA3343E3A
(1 row)
解密時,如果使用ecb加密的串,用cbc來解密,顯然得到的結果是不對的,反之亦然
postgres=# select encode(decrypt(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes-ecb`::text), `DATAENCRYPTIONYH`::bytea, `aes-ecb`), `escape`);
encode
---------------------------
6999217001930000722099991
(1 row)
postgres=# select encode(decrypt(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes-cbc`::text), `DATAENCRYPTIONYH`::bytea, `aes-cbc`), `escape`);
encode
---------------------------
6999217001930000722099991
(1 row)
postgres=# select encode(decrypt(ENCRYPT(DECODE(`6999217001930000722099991`,`escape`),`DATAENCRYPTIONYH`::bytea,`aes-ecb`::text), `DATAENCRYPTIONYH`::bytea, `aes-cbc`), `escape`);
encode
----------------------------------------------------------------
6999217001930000211x1B270350Tx03343250M_6246355{202`
(1 row)
小結
如果你發現同樣用到了AES演算法加密,但是得到的加密串不一樣,那麼請注意兩者用的mode, padding是否一致,如果不一致,結果肯定是不一樣的。
解密與加密的演算法、MODE、PADDING都需要一樣,才能保證正常的解密。
如果你的ORACLE或MYSQL用了ecb mode,那麼在PostgreSQL, Greenplum中解密時,請務必使用同樣的mode來解密。
參考
https://www.postgresql.org/docs/10/static/pgcrypto.html
《PostgreSQL 和 Greenplum pgcrypto 加解密bytea處理差異》
《固若金湯 – PostgreSQL pgcrypto加密外掛》
《PostgreSQL 如何實現網路壓縮傳輸或加密傳輸(openssl)》
man openssl
man enc
aes-[128|192|256]-cbc 128/192/256 bit AES in CBC mode
aes-[128|192|256] Alias for aes-[128|192|256]-cbc
aes-[128|192|256]-cfb 128/192/256 bit AES in 128 bit CFB mode
aes-[128|192|256]-cfb1 128/192/256 bit AES in 1 bit CFB mode
aes-[128|192|256]-cfb8 128/192/256 bit AES in 8 bit CFB mode
aes-[128|192|256]-ecb 128/192/256 bit AES in ECB mode
aes-[128|192|256]-ofb 128/192/256 bit AES in OFB mode
相關文章
- 如何為資料庫選擇最佳加密方法資料庫加密
- mysql innodb_autoinc_lock_mode 的與資料庫行為MySql資料庫
- Oracle MySQL PG選型OracleMySql
- 【譯】框架與庫的差異框架
- PostgreSQL與Oracle的sql差異SQLOracle
- ORACLE與MYSQL程式碼開發差異OracleMySql
- PostgreSQL:資料庫的選擇SQL資料庫
- Golang 針對 MySQL 資料庫表結構的差異 SQL 工具GolangMySql資料庫
- 比較兩個資料庫的差異資料庫
- MySQL與PostgreSQL:該選擇哪個開源資料庫?MySql資料庫
- 加密演算法介紹及加密演算法的選擇加密演算法
- GPRS與4G網路的技術差異與應用選擇
- java比較mysql兩個資料庫中差異JavaMySql資料庫
- oracle資料庫的ACFS圖形介面不可選擇Oracle資料庫
- Kotlin 操作符:run、with、let、also、apply 的差異與選擇KotlinAPP
- 資料庫差異備份與增量備份的不同之處資料庫
- openGauss資料與PostgreSQL的差異對比SQL
- 談談 mysql和oracle的使用感受 -- 差異MySqlOracle
- 技術分享|SQL和 NoSQL資料庫之間的差異:MySQL(VS)MongoDB資料庫MySqlMongoDB
- mpp 資料庫greenplum官方商業版本與開源版本的差異資料庫
- 【PG資料庫】PG資料庫的安裝及連線方法資料庫
- 比對兩個資料庫的差異:Java篇資料庫Java
- 基於知識圖譜與異常檢測的PG資料庫故障定位資料庫
- GPRS與4G網路:技術差異與應用選擇
- AES演算法:加密通訊的新選擇演算法加密
- MySQL資料庫索引選擇使用B+樹MySql資料庫索引
- 資料庫和資料湖的關鍵概念性差異資料庫
- MySQL 資料庫 InnoDB 和 MyISAM 資料引擎的差別MySql資料庫
- Oracle資料庫系統的安全性(轉)Oracle資料庫
- 不同資料庫SQL語法差異資料庫SQL
- Mysql pg oracle三種資料庫獲取月份、周的函式比較MySqlOracle資料庫函式
- 資料專案與erp專案的差異
- Android資料加密之異或加密演算法Android加密演算法
- pg_resetwal pg_resetxlog 重整 pg資料庫 wal 與pg_controldata 。 資料庫恢復。資料庫LDA
- 結構化資料與非結構化資料的差異
- 臨時表在Oracle資料庫與SQL Server資料庫中的異同Oracle資料庫SQLServer
- 關於Oracle資料庫與MySQL資料庫的幾點區別Oracle資料庫MySql
- 如何選擇合適的NoSQL資料庫SQL資料庫