Files
im_manager/docs/admin-adfahi-research/sql/消息加密密钥管理.sql
T

138 lines
6.6 KiB
SQL

-- 消息加密密钥管理。
-- 可重复执行。根 KEK 只在首次执行时生成,重复执行不会覆盖已有值。
SET NAMES utf8mb4;
SET @now := NOW();
SET @im_sql = IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_tenant_config'
AND COLUMN_NAME = 'message_encryption_enabled') = 0,
'ALTER TABLE `im_tenant_config` ADD COLUMN `message_encryption_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否启用消息加密'' AFTER `local_moderation_enabled`',
'SELECT 1'
);
PREPARE im_stmt FROM @im_sql;
EXECUTE im_stmt;
DEALLOCATE PREPARE im_stmt;
CREATE TABLE IF NOT EXISTS `im_message_encryption_keys` (
`id` bigint NOT NULL AUTO_INCREMENT,
`tenant_id` bigint NOT NULL COMMENT '商户ID',
`key_version` int unsigned NOT NULL COMMENT '密钥版本',
`algorithm` varchar(32) NOT NULL DEFAULT 'AES-256-GCM' COMMENT '数据加密算法',
`encrypted_dek` blob NOT NULL COMMENT '由根KEK包裹后的商户DEK',
`dek_nonce` varbinary(12) NOT NULL COMMENT '包裹DEK使用的随机nonce',
`status` varchar(16) NOT NULL DEFAULT 'pending' COMMENT 'pending/active/retired/disabled',
`activated_at` datetime DEFAULT NULL,
`retired_at` datetime DEFAULT NULL,
`remark` varchar(255) NOT NULL DEFAULT '',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_by` bigint NOT NULL DEFAULT 0,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_by` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_message_key_tenant_version` (`tenant_id`, `key_version`),
KEY `idx_im_message_key_tenant_status` (`tenant_id`, `status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商户消息加密密钥版本';
INSERT INTO `hg_sys_dict_type`
(`pid`, `name`, `type`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 0, 'IM内部安全材料', 'im_internal_secret', 9999,
'仅供服务端读取,通用字典接口禁止查询和维护', 1, @now, @now
WHERE NOT EXISTS (
SELECT 1 FROM `hg_sys_dict_type` WHERE `type` = 'im_internal_secret'
);
INSERT INTO `hg_sys_dict_data`
(`label`, `value`, `value_type`, `type`, `list_class`, `is_default`, `sort`, `remark`, `status`, `created_at`, `updated_at`)
SELECT 'core_material_01', TO_BASE64(RANDOM_BYTES(32)), 'string', 'im_internal_secret',
'', 2, 1, '消息DEK包裹根密钥KEK,请勿通过后台展示或修改', 1, @now, @now
WHERE NOT EXISTS (
SELECT 1 FROM `hg_sys_dict_data`
WHERE `type` = 'im_internal_secret' AND `label` = 'core_material_01'
);
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
SET @settingsId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imSystemSettings' LIMIT 1);
INSERT INTO `hg_admin_menu`
(`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`,
`permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`,
`frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`,
`status`, `created_at`, `updated_at`)
SELECT @settingsId, '消息密钥管理', 'imMessageEncryptionIndex', 'message-encryption/index',
'KeyOutlined', 2, '', '/imMessageEncryption/list', '', '/imMessageEncryption/index',
1, 'imManager', 0, 0, '', 0, 0, 0, 3,
CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '), 80,
'商户消息加密开关及密钥版本管理', 1, @now, @now
WHERE @settingsId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMessageEncryptionIndex');
SET @keyMenuId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imMessageEncryptionIndex' LIMIT 1);
UPDATE `hg_admin_menu`
SET `pid` = @settingsId,
`title` = '消息密钥管理',
`path` = 'message-encryption/index',
`icon` = 'KeyOutlined',
`permissions` = '/imMessageEncryption/list',
`component` = '/imMessageEncryption/index',
`active_menu` = 'imManager',
`level` = 3,
`tree` = CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' '),
`sort` = 80,
`hidden` = 0,
`status` = 1,
`updated_at` = @now
WHERE `id` = @keyMenuId;
INSERT INTO `hg_admin_menu`
(`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`,
`permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`,
`frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`,
`status`, `created_at`, `updated_at`)
SELECT @keyMenuId, '初始化密钥', 'imMessageEncryptionInitialize', '', '', 3, '',
'/imMessageEncryption/initialize', '', '', 1, '', 0, 0, '', 0, 1, 0, 4,
CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' tr_', @keyMenuId, ' '), 10, '', 1, @now, @now
WHERE @keyMenuId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMessageEncryptionInitialize');
INSERT INTO `hg_admin_menu`
(`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`,
`permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`,
`frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`,
`status`, `created_at`, `updated_at`)
SELECT @keyMenuId, '轮换密钥', 'imMessageEncryptionRotate', '', '', 3, '',
'/imMessageEncryption/rotate', '', '', 1, '', 0, 0, '', 0, 1, 0, 4,
CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' tr_', @keyMenuId, ' '), 20, '', 1, @now, @now
WHERE @keyMenuId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMessageEncryptionRotate');
INSERT INTO `hg_admin_menu`
(`pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`,
`permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`,
`frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`,
`status`, `created_at`, `updated_at`)
SELECT @keyMenuId, '切换消息加密', 'imMessageEncryptionSwitch', '', '', 3, '',
'/imMessageEncryption/switch', '', '', 1, '', 0, 0, '', 0, 1, 0, 4,
CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' tr_', @keyMenuId, ' '), 30, '', 1, @now, @now
WHERE @keyMenuId IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name` = 'imMessageEncryptionSwitch');
UPDATE `hg_admin_menu`
SET `level` = 4,
`tree` = CONCAT('tr_', @imRootId, ' tr_', @settingsId, ' tr_', @keyMenuId, ' '),
`updated_at` = @now
WHERE `pid` = @keyMenuId AND `type` = 3;
INSERT IGNORE INTO `hg_admin_role_menu` (`role_id`, `menu_id`)
SELECT 1, `id` FROM `hg_admin_menu`
WHERE `name` IN (
'imManager',
'imSystemSettings',
'imMessageEncryptionIndex',
'imMessageEncryptionInitialize',
'imMessageEncryptionRotate',
'imMessageEncryptionSwitch'
);