通用密钥环密钥管理功能
MySQL Server支持密钥环服务,该服务使内部服务器组件和插件能够安全地存储敏感信息,以便以后检索。
MySQL Server还包括一个用于密钥环密钥管理的SQL接口,实现为一组通用用户定义函数(UDF),这些函数可访问内部密钥环服务提供的功能。密钥环UDF包含在插件库文件中,该文件还包含keyring_udf
必须在调用UDF之前启用的插件。要使用这些UDF,必须启用诸如keyring_file
或的密钥环插件keyring_okv
。
这里描述的UDF是通用的,旨在与任何密钥环插件一起使用。给定的密钥环插件可能具有自己的UDF,这些UDF仅可用于该插件。请参见“特定于插件的密钥环密钥管理功能”。
以下各节提供了密钥环UDF的安装说明,并演示了如何使用它们。有关UDF调用的密钥环服务功能的信息,请参见“密钥环服务”。有关常规密钥环的信息,请参见“ MySQL密钥环”。
- 安装或卸载通用密钥环功能
- 使用通用密钥环功能
- 通用密钥环功能参考
安装或卸载通用密钥环功能
本节介绍如何安装或卸载密钥环用户定义功能(UDF),这些功能在也包含keyring_udf
插件的插件库文件中实现。有关安装或卸载插件和UDF的一般信息,请参见“MySQL服务器插件”和“安装和卸载用户定义的功能”。
密钥环UDF启用密钥环密钥管理操作,但是keyring_udf
还必须安装插件,因为如果没有它,UDF将无法正常工作。尝试在没有keyring_udf
插件的情况下使用UDF会导致错误。
要由服务器使用,插件库文件必须位于MySQL插件目录(由plugin_dir
系统变量命名的目录)中。如有必要,通过设置plugin_dir
服务器启动时的值来配置插件目录位置。
插件库文件的基本名称为keyring_udf
。每个平台的文件名后缀都不同(例如,.so
对于Unix和类似Unix的系统,.dll
对于Windows)。
要安装keyring_udf
插件和UDF,请使用INSTALL PLUGIN
和CREATE FUNCTION
语句(.so
根据需要调整平台的后缀):
INSTALL PLUGIN keyring_udfSONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_generateRETURNS INTEGERSONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_fetchRETURNS STRING SONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_length_fetchRETURNS INTEGERSONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_type_fetchRETURNS STRING SONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_storeRETURNS INTEGERSONAME 'keyring_udf.so';CREATE FUNCTION keyring_key_removeRETURNS INTEGERSONAME 'keyring_udf.so';
如果插件和UDF在主复制服务器上使用,请在所有从属服务器上也安装它们,以避免复制问题。
如前所述安装后,插件和UDF将保持安装状态,直到被卸载。要删除它们,请使用UNINSTALL PLUGIN
nd DROP FUNCTION
语句:
UNINSTALL PLUGIN keyring_udf;DROP FUNCTION keyring_key_generate;DROP FUNCTION keyring_key_fetch;DROP FUNCTION keyring_key_length_fetch;DROP FUNCTION keyring_key_type_fetch;DROP FUNCTION keyring_key_store;DROP FUNCTION keyring_key_remove;
使用通用密钥环功能
在使用密钥环用户定义功能(UDF)之前,请按照“安装或卸载通用密钥环功能”中提供的说明进行安装。
密钥环UDF受到以下约束:
要使用任何密钥环UDF,
keyring_udf
必须启用该插件。否则,将发生错误:ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate'; This function requires keyring_udf plugin which is not installed. Please install
要安装
keyring_udf
插件,请参阅安装或卸载通用密钥环功能。密钥环UDF调用密钥环服务功能(请参见“密钥环服务”)。服务功能依次使用已安装的任何密钥环插件(例如
keyring_file
或keyring_okv
)。因此,要使用任何密钥环UDF,必须启用某些基础密钥环插件。否则,将发生错误:ERROR 3188 (HY000): Function 'keyring_key_generate' failed because underlying keyring service returned an error. Please check if keyring plugin is installed and that provided arguments are valid for the keyring you are using.
要安装密钥环插件,
要使用任何密钥环UDF,用户必须拥有全局
EXECUTE
特权。否则,将发生错误:ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate'; The user is not privileged to execute this function. User needs to have EXECUTE
要向用户授予全局
EXECUTE
特权,请使用以下语句:GRANT EXECUTE ON *.*TO user;或者,如果您希望避免在授予
EXECUTE
用户访问特定密钥管理操作的同时授予全局特权,则可以定义“包装”存储的程序(本节稍后介绍的一种技术)。给定用户存储在密钥环中的密钥以后只能由同一用户操作。即,
CURRENT_USER()
键操作时的功能值必须与键存储在键环中时的值相同。(此约束排除了使用密钥环UDF来处理实例范围内的密钥,例如为InnoDB
支持表空间加密而创建的密钥)。为了使多个用户可以对同一键执行操作,可以定义“包装”存储的程序(本节稍后介绍的一种技术)。
- 密钥环UDF支持基础密钥环插件支持的密钥类型和长度。有关特定于特定密钥环插件的密钥的信息,请参见“支持的密钥环密钥类型和长度”。
要创建一个新的随机密钥并将其存储在密钥环中,请调用keyring_key_generate()
,将密钥的ID以及密钥类型(加密方法)及其长度(以字节为单位)传递给它。以下调用创建了一个2048位DSA加密密钥,名为MyKey
:
mysql>SELECT keyring_key_generate('MyKey', 'DSA', 256); +------------------------------------------- + | keyring_key_generate('MyKey', 'DSA', 256) | +------------------------------------------- + | 1 | +------------------------------------------- +
返回值1表示成功。如果无法创建密钥,则返回值为,NULL
并发生错误。原因之一可能是基础密钥环插件不支持密钥类型和密钥长度的指定组合。请参见“支持的密钥环密钥类型和长度”。
为了能够检查返回类型,而不管是否发生错误,请使用并测试变量值:SELECT ... INTO @var_name
mysql>SELECT keyring_key_generate('', '', -1)INTO @x; ERROR 3188 (HY000): Function 'keyring_key_generate' failed because underlying keyring service returned an error. Please check if a keyring plugin is installed and that provided arguments are valid for the keyring you are using. mysql>SELECT @x; +------ + | @x | +------ + | NULL | +------ + mysql>SELECT keyring_key_generate('x', 'AES', 16)INTO @x; mysql>SELECT @x; +------ + | @x | +------ + | 1 | +------ +
此技术也适用于其他密钥环UDF,这些密钥环UDF对于失败将返回一个值和一个错误。
传递给的ID keyring_key_generate()
提供了一种在后续UDF调用中引用密钥的方法。例如,使用密钥ID检索其类型为字符串或以字节为单位的长度作为整数:
mysql>SELECT keyring_key_type_fetch('MyKey'); +--------------------------------- + | keyring_key_type_fetch('MyKey') | +--------------------------------- + | DSA | +--------------------------------- + mysql>SELECT keyring_key_length_fetch('MyKey'); +----------------------------------- + | keyring_key_length_fetch('MyKey') | +----------------------------------- + | 256 | +----------------------------------- +
要检索键值,请将键ID传递给keyring_key_fetch()
。下面的示例用于HEX()
显示键值,因为它可能包含不可打印的字符。为了简洁起见,该示例还使用了一个短键,但请注意,较长的键可提供更好的安全性:
mysql>SELECT keyring_key_generate('MyShortKey', 'DSA', 8); +---------------------------------------------- + | keyring_key_generate('MyShortKey', 'DSA', 8) | +---------------------------------------------- + | 1 | +---------------------------------------------- + mysql>SELECT HEX(keyring_key_fetch('MyShortKey')); +-------------------------------------- + | HEX(keyring_key_fetch('MyShortKey')) | +-------------------------------------- + | 1DB3B0FC3328A24C | +-------------------------------------- +
密钥环UDF将密钥ID,类型和值视为二进制字符串,因此比较区分大小写。例如,的ID MyKey
和mykey
引用不同的密钥。
要删除密钥,请将密钥ID传递给keyring_key_remove()
:
mysql>SELECT keyring_key_remove('MyKey'); +----------------------------- + | keyring_key_remove('MyKey') | +----------------------------- + | 1 | +----------------------------- +
要混淆并存储您提供的密钥,请将密钥ID,类型和值传递给keyring_key_store()
:
mysql>SELECT keyring_key_store('AES_key', 'AES', 'Secret string'); +------------------------------------------------------ + | keyring_key_store('AES_key', 'AES', 'Secret string') | +------------------------------------------------------ + | 1 | +------------------------------------------------------ +
如前所述,用户必须具有全局EXECUTE
特权才能调用密钥环UDF,并且最初将密钥存储在密钥环中的用户必须是与该用户稍后对密钥执行后续操作的用户,这取决于CURRENT_USER()
每个密钥的有效值。 UDF调用。要允许对没有全局EXECUTE
特权或可能不是密钥“所有者”的用户进行密钥操作,请使用以下技术:
- 定义“包装器”存储的程序,这些程序封装了所需的键操作,并且其
DEFINER
值等于键所有者。 - 将
EXECUTE
特定存储程序的特权授予应该可以调用它们的单个用户。 - 如果包装存储程序执行的操作不包括密钥创建,请使用
DEFINER
存储程序定义中名为的帐户预先创建任何必需的密钥。
这种技术使密钥可以在用户之间共享,并为DBA提供了更细粒度的控制,使其可以在无需授予全局特权的情况下对谁可以执行密钥进行操作。
下面的示例演示如何设置SharedKey
DBA拥有的名为的共享密钥以及get_shared_key()
提供对当前密钥值的访问的存储函数。任何具有该EXECUTE
功能特权的用户都可以检索该值,该特权是在key_schem
模式中创建的。
从一个MySQL管理帐户('root'@'localhost'
在此示例中),创建管理模式和存储的函数以访问密钥:
mysql>CREATE SCHEMA key_schem ; mysql>CREATE DEFINER = 'root'@'localhost'FUNCTION key_schem .get_shared_key()RETURNS BLOBREADS SQL DATA RETURN keyring_key_fetch('SharedKey');
从管理帐户,确保共享密钥存在:
mysql>SELECT keyring_key_generate('SharedKey', 'DSA', 8); +--------------------------------------------- + | keyring_key_generate('SharedKey', 'DSA', 8) | +--------------------------------------------- + | 1 | +--------------------------------------------- +
从管理帐户中,创建要授予密钥访问权限的普通用户帐户:
mysql>CREATE USER 'key_user'@'localhost'IDENTIFIED BY 'key_user_pwd';
通过该key_user
帐户,验证没有适当的EXECUTE
特权,新帐户是否无法访问共享密钥:
mysql>SELECT HEX(key_schem .get_shared_key()); ERROR 1370 (42000): execute command denied to user 'key_user'@'localhost' for routine 'key_schema.get_shared_key'
从管理帐户,授EXECUTE
给key_user
了存储功能:
mysql>GRANT EXECUTE ON FUNCTION key_schem .get_shared_keyTO 'key_user'@'localhost';
从key_user
帐户中验证密钥现在可以访问:
mysql>SELECT HEX(key_schem .get_shared_key()); +---------------------------------- + | HEX(key_schema.get_shared_key()) | +---------------------------------- + | 9BAFB9E75CEEB013 | +---------------------------------- +
通用密钥环功能参考
对于每个通用密钥环用户定义函数(UDF),本节描述其用途,调用顺序和返回值。有关可在何种条件下调用这些UDF的信息,请参阅《使用通用密钥环函数》。
keyring_key_fetch(key_id)
给定一个密钥ID,对密钥进行反模糊处理并返回。
参数:
key_id
:指定密钥ID的字符串。
返回值:
NULL
如果键不存在,则将键值作为成功字符串返回,否则返回NULL
错误。注意
使用检索
keyring_key_fetch()
到的密钥值必须遵守“支持的密钥环密钥类型和长度”中所述的常规密钥环UDF限制。可以使用密钥环服务功能存储长度大于该长度的密钥值(请参见“密钥环服务”),但是如果使用进行检索,则将keyring_key_fetch()
其截断为通用密钥环UDF限制。例:
mysql>
SELECT keyring_key_generate('RSA_key', 'RSA', 16); +-------------------------------------------- + | keyring_key_generate('RSA_key', 'RSA', 16) | +-------------------------------------------- + | 1 | +-------------------------------------------- + mysql>SELECT HEX(keyring_key_fetch('RSA_key')); +----------------------------------- + | HEX(keyring_key_fetch('RSA_key')) | +----------------------------------- + | 91C2253B696064D3556984B6630F891A | +----------------------------------- + mysql>SELECT keyring_key_type_fetch('RSA_key'); +----------------------------------- + | keyring_key_type_fetch('RSA_key') | +----------------------------------- + | RSA | +----------------------------------- + mysql>SELECT keyring_key_length_fetch('RSA_key'); +------------------------------------- + | keyring_key_length_fetch('RSA_key') | +------------------------------------- + | 16 | +------------------------------------- +该示例用于
HEX()
显示键值,因为它可能包含不可打印的字符。为了简洁起见,该示例还使用了一个短键,但请注意,较长的键可提供更好的安全性。keyring_key_generate(key_id,key_type,key_length)
生成具有给定ID,类型和长度的新随机密钥,并将其存储在密钥环中。类型和长度值必须与基础密钥环插件支持的值一致。请参见“支持的密钥环密钥类型和长度”。
参数:
key_id
:指定密钥ID的字符串。key_type
:指定密钥类型的字符串。key_length
:一个整数,以字节为单位指定密钥长度。
返回值:
如果成功返回1,否则返回
NULL
错误。例:
mysql>
SELECT keyring_key_generate('RSA_key', 'RSA', 384); +--------------------------------------------- + | keyring_key_generate('RSA_key', 'RSA', 384) | +--------------------------------------------- + | 1 | +--------------------------------------------- +keyring_key_length_fetch(key_id)
给定密钥ID,返回密钥长度。
参数:
key_id
:指定密钥ID的字符串。
返回值:
NULL
如果密钥不存在,则返回密钥长度(以字节为单位),以整数表示成功,如果失败,则返回NULL
一个错误,否则返回错误。例:
请参阅的说明
keyring_key_fetch()
。keyring_key_remove(key_id)
从密钥环中删除具有给定ID的密钥。
参数:
key_id
:指定密钥ID的字符串。
返回值:
如果成功或
NULL
失败,则返回1 。例:
mysql>
SELECT keyring_key_remove('AES_key'); +------------------------------- + | keyring_key_remove('AES_key') | +------------------------------- + | 1 | +------------------------------- +keyring_key_store(key_id,key_type,key)
混淆密钥并将其存储在密钥环中。
参数:
key_id
:指定密钥ID的字符串。key_type
:指定密钥类型的字符串。key
:指定键值的字符串。
返回值:
如果成功返回1,否则返回
NULL
错误。例:
mysql>
SELECT keyring_key_store('new key', 'DSA', 'My key value'); +----------------------------------------------------- + | keyring_key_store('new key', 'DSA', 'My key value') | +----------------------------------------------------- + | 1 | +----------------------------------------------------- +keyring_key_type_fetch(key_id)
给定密钥ID,则返回密钥类型。
参数:
key_id
:指定密钥ID的字符串。
返回值:
NULL
如果密钥不存在,则返回密钥类型为成功的字符串,否则返回NULL
失败的错误。例:
请参阅的说明
keyring_key_fetch()
。