前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用MySQL Keyring 的 SECRET类型密钥执行非对称加密

使用MySQL Keyring 的 SECRET类型密钥执行非对称加密

作者头像
MySQLSE
发布2020-09-28 15:40:55
1.9K0
发布2020-09-28 15:40:55
举报
文章被收录于专栏:MySQL解决方案工程师

作者:Mike Frank 译:徐轶韬

仅用于通过应用程序使用解密/加密

以下是一个示例,演示应用程序使用公钥进行非对称加密数据。在MySQL 8.0.19中,添加了支持Keyring技术的SECRET密钥类型。使用此技术,用户可以使用以下方法安全地管理自己的密钥:

Oasis KMIP协议实现:

  • Oracle Key Vault
  • Gemalto KeySecure
  • Thales Vormetric Key Management Server
  • Fornetix Key Orchestration
  • New! Townsend Alliance Key Manager

其他用于密钥管理的API:

  • 使用自己的密钥– 加密密钥文件
  • Hashicorp Vault
  • 更多

先决条件

MySQL企业版8.0.19或更高版本

代码语言:javascript
复制
select @@version;

演示开始

以管理员身份(以admin身份运行示例– root@localhost) 安装MySQL Keyring

检查一下

代码语言:javascript
复制
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';

下一步,安装MySQL Keyring UDF

代码语言:javascript
复制
INSTALL PLUGIN keyring_udf SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_generate RETURNS INTEGER
SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_fetch RETURNS STRING
SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER
SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_type_fetch RETURNS STRING
SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_store RETURNS INTEGER
SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_remove RETURNS INTEGER
SONAME 'keyring_udf.so';

安装MySQL企业版加密

代码语言:javascript
复制

现在可以创建一个示例–在这种情况下,我们要

  1. 通过推入keyring 来保护私钥
    • 如果您丢失了私钥–您将丢失所有加密数据。
    • 如果密钥被盗–小偷可以读取您的敏感数据。
  2. 客户端应用程序的MySQL用户只能使用公钥加密敏感数据
  3. 另一个用户可以使用私钥解密该数据

创建用于存储敏感“秘密”数据的表

已经准备好了,让我们看一下这个例子:

代码语言:javascript
复制
CREATE TABLE `secretdb`.`secrets_table`
(`secid` INT NOT NULL, 
`secrets_tablecol` VARBINARY(3000) NOT NULL);

创建私有PEM key并将其存储在MySQL keyring

代码语言:javascript
复制
SELECT keyring_key_store
('MySecret', 'SECRET',
create_asymmetric_priv_key('RSA', 2048));

查看一下

代码语言:javascript
复制
select keyring_key_fetch('MySecret');

创建一个函数,允许应用程序用户获取公钥并加密“秘密”。

在这种情况下,用户无法运行keyring_key_fetch(他们没有权限),因此,该函数将SQL SECURITY作为DEFINER(在本例中为root)运行。此函数将仅返回公钥(从keyring的私钥中提取出来)。

代码语言:javascript
复制
CREATE DEFINER = 'root'@'localhost' 
FUNCTION `secretdb`.`secdb_public_key`() 
RETURNS TEXT(500) deterministic
SQL SECURITY DEFINER
RETURN 
RTRIM(CREATE_ASYMMETRIC_PUB_KEY('RSA',keyring_key_fetch('MySecret')));

尝试一下

代码语言:javascript
复制
select `secretdb`.`secdb_public_key`();

创建应用程序的MySQL用户,并对表和函数进行访问授权。

代码语言:javascript
复制
CREATE USER 'appuser'@'%' IDENTIFIED BY <password>;
GRANT USAGE ON *.* TO `appuser`@`%`;

现在–试试看–以该用户身份登录

获取公钥

代码语言:javascript
复制
select `secretdb`.`secdb_public_key`() into @pubk; GRANT SELECT, INSERT ON `secretdb`.* TO `appuser`@`%`'; GRANT EXECUTE ON FUNCTION `secretdb`.`secdb_public_key` TO 'appuser`@'%';

接下来,让我们创建一个“秘密”。

代码语言:javascript
复制
SET @secretphrase='Sooo very secret 1';

定义密钥长度和算法

代码语言:javascript
复制
SET @key_len = 2048; SET @algo = 'RSA';

加密数据

代码语言:javascript
复制
SET @enc_value = ASYMMETRIC_ENCRYPT(@algo, @secretphrase, @pubk);

查看其加密

代码语言:javascript
复制
select 'Encrypted secret ', @enc_value;

插入表

代码语言:javascript
复制
INSERT INTO `secretdb`.`secrets_table` (`secid`, `secrets_tablecol`) VALUES (1, @enc_value);

再做另外一个秘密

代码语言:javascript
复制
SET @secretphrase='Sooo very secret 2'; select @secretphrase; Set @enc_value = ASYMMETRIC_ENCRYPT(@algo, @secretphrase, @pubk); select 'Encrypted secret 2', @enc_value;
代码语言:javascript
复制
INSERT INTO `secretdb`.`secrets_table` (`secid`,`secrets_tablecol`) VALUES (2, @enc_value);

查看加密的数据

代码语言:javascript
复制
select * from `secretdb`.`secrets_table`;

注意:没有私钥,appuser无法解密。

以root身份登录并解密数据

代码语言:javascript
复制
select `secrets_table`.`secrets_tablecol` into @encrsecretphrase from `secretdb`.`secrets_table` where secid=2;
select @encrsecretphrase;
代码语言:javascript
复制
select keyring_key_fetch('MySecret') into @privappprivpkey; select @privappprivpkey; Set @enc_pp = ASYMMETRIC_DECRYPT(@algo, @encrsecretphrase, @privappprivpkey); select 'Secret', @enc_pp;

作为root用户,可以看到数据。

现在,我们要提供除root用户以外的其他用户对私钥的访问权限。

代码语言:javascript
复制
CREATE DEFINER = 'root'@'localhost' FUNCTION `secretdb`.`secdb_private_key`() RETURNS TEXT(500) deterministic SQL SECURITY DEFINER RETURN rtrim(keyring_key_fetch('MySecret'));

以root身份测试

代码语言:javascript
复制
select `secretdb`.`secdb_private_key`();

让我们创建另一个用户-该用户也有权访问数据。

代码语言:javascript
复制
CREATE USER 'privuser'@'%' IDENTIFIED BY <password>;
GRANT USAGE ON *.* TO 'privuser'@'%'; 
GRANT SELECT ON `secretdb`.* TO 'privuser'@'%';
GRANT EXECUTE ON FUNCTION `secretdb`.`secdb_private_key` TO 'privuser'@'%';

测试访问

代码语言:javascript
复制
select `secretdb`.`secdb_private_key`();

检索数据

代码语言:javascript
复制
SET @algo = 'RSA'; select `secrets_table`.`secrets_tablecol` into @encrsecretphrase from `secretdb`.`secrets_table` where secid=2;

看-它已经加密

select @encrsecretphrase;

让我们解密

获取私钥

代码语言:javascript
复制
select secretdb.secdb_private_key() into @privappprivpkey;

用私钥解密数据

代码语言:javascript
复制
Set @enc_pp = ASYMMETRIC_DECRYPT(@algo, @encrsecretphrase, @privappprivpkey);

查看“秘密”

代码语言:javascript
复制
select 'The secret is', @enc_pp;

演示结束。

常见问题

如果我想加密/解密应用程序中的数据怎么办?

您可以使用带有公共或私有密钥(PEM格式)的openssl或兼容库来实现。只要确保您以二进制形式插入/更新数据即可。

如果我的数据大于非对称加密可以处理的数据怎么办?

进行混合加密,您可以获得与公钥相同的好处。

由于现在支持SECRET,因此无需将密钥存储在安全性较低的表中-现在您可以将它们作为SECRET类型放置在更安全的keyring上。

展望未来

试试看,不会花很长时间。通过keyring,非对称加密,对称加密,权限和其他访问控制,解决数据安全性的方法还有多种多样的选择。

例如,用户只能将公钥存储在主服务器上,将私钥存储在只读从服务器上。私钥只能存在于应用程序中,不能存在于mysql keyring上。或者,可以编写一个具有用户权限的函数,该函数可以在拥有权限时解密,但根本不显示私钥。

如果您遇到安全挑战,请告诉我们。

与往常一样,感谢您使用MySQL。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MySQL解决方案工程师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 作者:Mike Frank 译:徐轶韬
  • 仅用于通过应用程序使用解密/加密
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档