数据库加密
正如在数据库加密概述页面中所解释的,SmartEDB提供了使用标准AES加密或通过自定义加密实现加密内存中数据库和持久数据库的功能,以及对数据库快照和备份文件进行加密。
数据加密
内存中数据的加密由传递给mco_db_open_dev()
的参数结构mco_db_params_t中的cipher_key
元素控制。如果此参数不为NULL
,则页面在保存之前会使用AES或自定义加密算法进行单独加密。
此外,还可以通过在线备份功能启用加密。只需指定mco_backup_create()
和mco_backup_restore()
函数的cipher
参数,即可启用备份文件的加密。这个选项与数据库参数mco_db_params_t::cipher_key
无关。
当指定了mco_db_params_t::cipher_key
字段时,数据库快照文件将由mco_db_save()
函数加密,并由mco_db_load()
函数解密。
请务必确保在保存和加载加密快照时使用完全相同的密码密钥。
加密算法的选择取决于与应用程序链接的库。AES算法的实现可以在mcocryptaes
库中找到。
有关自定义加密算法实现的详细信息,请参阅键值包含索引和覆盖索引页面。
内存数据库加密
只有在指定了 cipher_key
并且在 mco_db_params_t.mode_mask
字段中设置了 MCO_DB_INMEMORY_PROTECTION
选项时,才会启用内存页加密。MCO_DB_INMEMORY_PROTECTION
模式将为应用程序正在访问的页创建一个哈希表。
在既定时间内连接可访问的最大页面数(默认值为 32)需通过mco_db_params_t 结构体中的 max_active_pages
字段进行指定。
此哈希表中的约束数量(用于在多个线程并发访问的情况下尽量减少锁冲突的数量)可以通过 mco_db_params_t 的 page_hash_bundles
字段指定。(此值应理想地设置为最大并发级别,即 CPU 核心的数量,默认值为 32)。
以下代码片段演示了如何使用 C API 启用加密:
int main(int argc, char* argv[])
{
MCO_RET rc;
mco_db_h db = 0;
mco_device_t dev[1];
mco_db_params_t db_params;
...
/* 初始化并自定义数据库参数 */
mco_db_params_init ( &db_params ); /* 用默认值初始化参数 */
db_params.mem_page_size = 128; /* 设置内存存储的页面大小 */
db_params.disk_page_size = 0; /* 为内存存储设置页大小为0 */
db_params.db_max_connections = 1; /* 设置与数据库连接的总数 */
db_params.cipher_key = "my_secure_key"; /* 设置加密密钥文件名 */
db_params.mode_mask = MCO_DB_INMEMORY_PROTECTION; /* 设置模式掩码 */
rc = mco_db_open_dev(db_name, genericdb_get_dictionary(), dev, N_DEVICES, &db_params );
if ( MCO_S_OK == rc )
{
/* 连接到数据库,获取数据库句柄 */
mco_db_connect(db_name, &db); /* 没有恢复连接数据 */
...
}
内存保护只能用于全内存数据库。因此,如果在使用 mcovtdsk
库时指定了此模式,函数 mco_db_open_dev()
或 mco_db_load()
将返回错误代码 MCO_E_ILLEGAL_PARAM
。
性能损失
数据库页面的加密可能会使应用程序速度降低 2 到 10 倍,尤其是对于索引操作。
使用 MCO_DB_INCLUSIVE_BTREE
选项有助于减轻这种性能损失
有关详细信息,请参阅键值包含索引和覆盖索引页面。
压缩与加密
如果设置了 mco_db_params_t::mode_mask
选项MCO_DB_INMEMORY_COMPRESSION
,则内存页将使用 ZIP 算法进行压缩。如果除了模式掩码选项 MCO_DB_INMEMORY_COMPRESSION
之外还设置了 mco_db_params_t::cipher_key
,则临时数据库页将同时进行压缩和加密。但这种组合与磁盘管理器不兼容,因此压缩加加密不适用于混合数据库。
持久数据库加密
通过操作系统的虚拟内存页面保护机制,SmartEDB提供了保护持久数据库内存区域的功能,包括为存储和缓存(页面池)分配的内存。
请注意,这项功能仅在UNIX平台上可用,并且建议仅用于调试目的。
持久存储上的数据加密由传递给mco_db_open_dev()
的参数结构mco_db_params_t 中的cipher_key
元素控制。如果此参数不为NULL
,则页面在保存到“磁盘”之前会使用AES或自定义加密算法进行加密,并在从“磁盘”加载时解密。每个页面都是单独加密的。
AES是一种对称加密算法,在第一次处理时对数据进行加密,在第二次处理时将数据解密回其原始形式。因此,加密API中没有单独的加密和解密函数,而只有一个encrypt()
函数来完成这两项任务。
存根库mcocryptstub
包含空API实现,会在遇到加密请求时返回错误代码MCO_E_UNSUPPORTED
并停止处理。这个库为开发人员提供了一个框架,以便他们可以实现自己的自定义加密算法。
数据库外部的其他文件的加密
除了保护持久性和临时数据库之外,加密还可用于保护:
- 由函数
mco_db_save()
和mco_class_save()
制作的数据库快照; - 由
mco_translog_start()
创建的 TL 事务日志; - 由函数
mco_backup_create()
创建的备份文件。
数据库快照和事务日志文件的加密与磁盘和内存页面的加密一样,只需指定 cipher_key
字段即可自动启用。
备份操作的加密与数据库打开参数无关,而是直接通过传递给函数 mco_backup_create()
和 mco_backup_restore() 的 cipher
参数来指定。
加密库
请使用以下链接查看为您的开发平台提供的 AES 加密算法库和“存根”库(以及其他库):
- Unix-Linux:用于标准Unix或Linux 64位或32位平台的静态库;
- Windows:用于Windows 7(或更高版本)平台的静态库;
- Integrity:Green Hills Integrity OS静态库;
- VxWorks:VxWorks OS静态库。