摘要:采用加密技術是保護數據庫信息的一種較為有效的手段。在數據庫中對數據進行加密保護,其加密機制主要涉及加密算法、加密粒度、密鑰生成和管理、查詢操作的實施以及對系統性能的影響等五個方面。該文針對加密粒度機制和對開源的PostgreSQL數據庫研究的基礎上提出了幾種實現數據庫數據加密的加密方案,并基于實際相關數據庫安全平臺課題的研究簡要分析了這幾種方法的優點與不足,為未來實現完備的數據庫保護提供一些借鑒。
關鍵詞:數據庫加密;加密粒度;字段加密;PostgreSQL數據庫
中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2009)33-9130-02
Methods of Achieving Field-Encryption Based on PostgreSQL
LI Xin-jun, ZHANG Yan-jing
(Jiangnan Institute of Computing Technology, Wuxi 214083, China)
Abstract: Encryption technology to protect the database information is an effective means. In the database to protect data, the encryption mechanism mainly involves encryption algorithm, encryption granularity, key generation and management, the implementation of query operators as well as the impact of system performance in five aspects. In this paper, based on the study of encryption granularity and PostgreSQL open source database, several methods are , and based on the actual issues related to database security platform for the study of this brief analysis of the merits of several methods and inadequate for the future to achieve a comprehensive protection database to provide some references.
Key words: database encryption; encryption granularity; field-encryption; PostgreSQL database
作為應用最廣泛的信息存儲和處理系統,數據庫中存在大量敏感數據,如何防止數據被竊取和篡改是重中之重。加密技術是提高數據庫安全的一個重要手段,在對數據庫中存儲數據進行加密時,需要結合它們的特點,對加密算法、加密粒度以及加密方式進行合理選擇。比如,在選擇加密算法時,對加密尤其是解密速度要求比較快,不能因為加/解密過程而導致系統性能大幅度下降。其次,應當支持靈活的加密粒度。根據用戶的需要,能夠選擇對數據庫、表、記錄、字段、數據項進行加密。同時,還應結合目前DBMS選擇適當加密方式。
但不是什么加密方法和方式都是適合數據庫的,在加密數據的同時,也會帶來一些相關問題,如果處理不好,不僅會降低數據庫的安全性,而且還會帶來其它如性能的影響。
本文簡要介紹和分析了在一個基于開源數據庫PostgreSQL的安全數據庫系統研究的基礎上,如何針對PostgreSQL數據庫的存儲數據的不同層次,對數據庫的文件(或表、頁)、記錄、字段等多個層次實現了加密。
1 數據庫不同加密粒度實現
按照PostgreSQL數據庫的結構層次,數據庫的加密粒度可以分為相應的數據庫級、表級、記錄級、字段級和數據項級。根據不同的應用需要,選擇合適的加密粒度。
1.1 對整個數據庫加密
加密整個數據庫,就是對數據庫中所有的系統表、數據表、索引、視圖和存儲過程等進行加密處理。這種加密方法簡單快捷,只需對相應數據庫文件進行加密處理即可,對于企業或者用戶簡單的備份整個數據庫,可以采取這種操作方便加密粒度。但是,使用中的數據庫如果采用這種方法則會非常不合適,因為數據庫中的數據共享性高,會同時被多個用戶和應用訪問使用,即使只需要查詢一條記錄,也需要對整個數據庫進行解密,對系統性能會產生極大的影響。因此對此整個數據庫加密的方式我們不作過多的研究和討論。
1.2 數據庫的表級(頁面)加密
安全數據庫將表分成兩大類,含加密字段的表和不含加密字段的表。對于加密的數據表則整個塊加密,否則不加密,且每塊使用一個密鑰。安全數據庫中,如果一個表中存放敏感數據,那么這個表的每一個頁面的數據域在內存中是明文,在外存中是密文。
表級加密的對象是數據庫中的表。與數據庫級加密比較,采用表級加密粒度,系統的查詢性能會有所改善,因為對于未加密表的查詢,與傳統查詢方法一樣,系統性能不會受到影響,對于加密表的查詢,只需要解密對應的加密表,而不要解密整個數據庫。在實行表級加密時,可以采用對存儲數據的磁盤塊(頁面)進行加密。這種方法與DBMS集成時,需要對DBMS內部一些核心模塊進行修改,包括對詞法分析器、解釋器和查詢執行器的修改,這里我們對開放源代碼的數據庫管理系統PostgreSQL的源碼進行修改。
1.2.1 加解密數據結構
加密函數:
Char cipherpage(char *buffer,int size,BlockNumber blocknum, Relation reln);
解密函數:
Char decipherpage(char *buffer,int size,BlockNumber blocknum, Relation reln);
輸入:
Buffer:加解密數據塊所在內存緩沖區;
Size:數據塊大小;
Blocknum:數據塊定位信息,需要寫入或讀出的數據塊;
Reln:記錄數據庫名,數據庫關系表,數據空間的信息;
返回值:
加解密成功后,返回數據塊所在的內存緩沖區。
1.2.2 加解密流程的實現
當DBMS將內存中的頁面寫出到外存中時,首先查詢安全字典,如果需要加密存儲,則用安全字典中當前密鑰加密。在將數據從外存讀入內存后,如果頁頭標識頁面是加密過的(由函數iscryptic()進行判斷),則取出相應的密鑰解密。加密時,只加密頁面中的數據域。這里也是由iscryptic()對進行讀寫的關系表進行判斷是否需要加解密,來對當前的數據塊進行加密或解密。解密時,當數據塊從外存讀入內存時,如果頁頭標識頁面是加密過的,則從安全字典中取出相應的密鑰解密數據域。加解密的密鑰通過主密鑰和頁塊的ID計算得出。
我們跟蹤數據的寫入和讀入流程,找到寫入和讀出數據塊(block)的位置,對該數據塊進行加解密。如圖1。
和對整個數據庫加密一樣,對數據庫進行表級加密實現方法簡單,但是加密的粒度較粗,一張表中會含有大量不需要加密的數據,這樣也會導致效率低下。
1.3 使用TOAST技術實現字段加密
使用TOAST技術,將加密的字段從原始的數據中分離出來,單獨存放。按照此種處理方案,同一個表中的明文密文存放在不同的文件或頁面中。
首先對TOAST (The Oversized-Attribute Storage Technique,超大尺寸字段存儲技術)進行一個簡單的概述。
PostgreSQL 數據庫的頁面大小是固定的(通常是 8Kb),并且不允許行跨越多個頁面,因此不可能直接存儲非常大的字段值。為了突破這個限制,大的字段值被壓縮和/或打碎成多個物理行。(這些事情對用戶都是透明的)。這個技術的昵稱是 TOAST(\"切片面包之后最好的東西\")。TOAST 代碼只有在準備向某表中存儲超過 BLCKSZ/4 字節(通常是 2KB)的行的時候才會觸發。TOAST 代碼將在對應于主表的TOAST表中壓縮和/或另存字段值,直到數值比 BLCKSZ/4 字節短,或者無法得到更好的結果的時候才停止。
1.3.1 字段加密的實現
借助于TOAST技術我們可以將TOAST 代碼的觸發時機移植到當需要對某一數據庫表的字段進行加密時。這樣主表中需要加密的字段中只是存儲實際已經加密的字段數據所在位置的索引值,實現的關鍵技術就是學習TOAST技術,這是實現的難點。
需要加密字段的數據在這里不是被分裂成(壓縮后)固定字節的塊后被存儲到相應的TOAST表中,而是每個被加密后的字段數據塊都作為獨立的行在TOAST表里為所屬主表存儲。每個TOAST 表都有chunk_id字段(一個表示特定TOAST值的OID)、chunk_seq(一個序列號,存儲該塊在數值中的位置)、chunk_data(該塊實際的數據)。在chunk_id 和chunk_seq上有一個唯一索引,提供對數值的快速檢索。因此,一個表示線外 TOAST 值的指針數據需要存儲要查閱的 TOAST 的OID和特定數值的OID(它的chunk_id)。這樣在主表中依據這些標識就可以順利找到被加密的字段,解密后即可使用。
TOAST 過的字段的大體積數值只是在把結果集發送給客戶端的時候才抽出來。因此,主表要小得多,并且它的大部分行都存儲在共享緩沖區里,因此就可以不需要任何線外存儲。排序集也縮小了,并且排序將更多地在內存里完成。TOAST 表存儲將近一半大小的裸數據,而主表只包含全部數據的 10%,這與在一個非 TOAST 的表對比起來,沒有任何運行時的區別。因此我們不必擔心TOAST帶來性能上的影響,如圖2所示。
與前面幾種數據庫加密方法不同,對數據庫進行字段加密不需要對所有的數據進行加密,加密的粒度更小,對于不需要訪問到的記錄,完全不需要進行任何操作,所以使用起來效率會高一些。但是由于每一個字段都必須有一個密鑰與之匹配,因此產生和管理記錄密鑰比較復雜。以記錄為單位的加密分析與以字段為單位的加密情況相似。這里就不再進行敘述。
1.4 其他方式
在PostgreSQL數據庫中,所有的記錄都被構造成一個TUPLE。在構造的過程中,將加密列上的屬性進行加密,保障內存中的數據是加密的,當一條記錄被引用時根據TUPLE中的標識對其相應的字段進行解密,如圖3所示。
2 結束語
本文基于PostgreSQL數據庫自身特點簡要討論了幾種 數據庫不同加密粒度式,用戶根據應用場合的不同, 可分別選用以數據庫表、記錄、字段作為加密基本單位的方案。由于層次不同, 這三個方案的適用環境與實現難度各不相同。一般而言, 加密單位越小, 適用范圍越廣, 但實現時的困難也越大。而數據庫的安全性仍然不斷面臨新的安全技術挑戰,這有待我們去進一步解決。
參考文獻:
[1] 王正飛.數據庫加密技術及其應用研究[D].復旦大學,2005.
[2] 曾凡號.數據庫加密技術研究[J].軟件導刊,2006(9).
[3] 楊寅春,李麗萍,何守才.基于Oracle DBMS的數據庫系統安全加固模型[J].計算機科學,2005.
[4] 夏明.數據庫加密與驗證的算法和實現機制研究[D].浙江工業大學,2005(12).