MySQL 8.0.30于2022年7月26日正式发行。在这个版本里,除了为数据加密功能增加了KDF(Key Derivation Function),还为企业版发布了新的加密组件,以替代之前基于OpenSSL的UDF。
KDF
MySQL具有SQL级别的加密功能,社区版的MySQL提供了AES_DECRYPT(),AES_ENCRYPT()函数用于数据的加密和解密,函数使用AES(Advanced Encryption Standard)加密算法,密钥长度可以选择 128bit、196bit,或者256bit。加密函数AES_DECRYPT(str,key_str[,init_vector][,kdf_name][,salt][,info | iterations])通过使用“key_str”密钥,对“str”字符进行加密,返回二进制的字符。解密函数AES_DECRYPT(crypt_str,key_str[,init_vector][,kdf_name][,salt][,info | iterations])则通过使用“key_str”密钥,对“crypt_str”进行解密,返回明文字符。从8.0.30开始,MySQL支持使用KDF,函数根据“key_str”中传递的信息和在其他参数中提供的salt(盐值)或附加信息创建一个密码学上的强密钥。派生密钥用于加密和解密数据,它保留在MySQL 服务器实例中,用户无法访问。KDF提供了更好的安全性,比在使用函数时指定自己的预生成密钥或通过简单的方法派生的密钥更好。
使用KDF生成密钥,进行加密、解密的示例如下:
--生成密钥用语
MySQL localhost:3350 ssl SQL > SET @key_str = SHA2('生成密钥用语',512);
Query OK, 0 rows affected (0.0003 sec)
--设置KDF名称
MySQL localhost:3350 ssl SQL > SET @kdf_name = 'hkdf';
Query OK, 0 rows affected (0.0002 sec)
--设置KDF使用的盐值
MySQL localhost:3350 ssl SQL > SET @salt = 'mysqlse';
Query OK, 0 rows affected (0.0001 sec)
--设置KDF用的其他信息
MySQL localhost:3350 ssl SQL > SET @info = 'mysql8030';
Query OK, 0 rows affected (0.0003 sec)
--使用加密函数进行加密
MySQL localhost:3350 ssl SQL > SET @crypt_str = AES_ENCRYPT('这是秘密不能告诉其他人',@key_str,'',@kdf_name,@info);
Query OK, 0 rows affected (0.0004 sec)
--使用解密函数进行解密
MySQL localhost:3350 ssl SQL > SELECT AES_DECRYPT(@crypt_str,@key_str,'',@kdf_name,@info);
+-----------------------------------------------------+
| AES_DECRYPT(@crypt_str,@key_str,'',@kdf_name,@info) |
+-----------------------------------------------------+
| 这是秘密不能告诉其他人 |
+-----------------------------------------------------+
1 row in set (0.0005 sec)
关于KDF具体的使用方法,请读者访问官网手册“https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_aes-encrypt”。
MySQL 企业版加密
MySQL企业版包含一组在SQL级别公开OpenSSL功能的加密函数。通过这些函数,企业应用可以进行如下操作:
在 MySQL 8.0.30 之前的版本中,这些函数基于 openssl_udf共享库。从 MySQL 8.0.30 开始,它们由 MySQL component_enterprise_encryption 组件提供。
下面举例介绍企业版加密的部分功能,示例的内容包括:
创建私钥/公钥对:
-- 设置加密算法
MySQL localhost:3350 ssl SQL > SET @algo = 'RSA';
Query OK, 0 rows affected (0.0004 sec)
-- 设置密钥长度
MySQL localhost:3350 ssl SQL > SET @key_len = 2048;
Query OK, 0 rows affected (0.0003 sec)
-- 创建私钥
MySQL localhost:3350 ssl SQL > SET @priv = create_asymmetric_priv_key(@algo, @key_len);
Query OK, 0 rows affected (0.1664 sec)
-- 利用私钥创建公钥
MySQL localhost:3350 ssl SQL > SET @pub = create_asymmetric_pub_key(@algo, @priv);
Query OK, 0 rows affected (0.0006 sec)
--可以查看密钥
MySQL localhost:3350 ssl SQL > SELECT @priv;
使用公钥加密数据,使用私钥解密:
--加密数据
MySQL localhost:3350 ssl SQL > SET @ciphertext = asymmetric_encrypt(@algo, '这是秘密', @pub);
Query OK, 0 rows affected (0.0005 sec)
--查看加密后的数据
MySQL localhost:3350 ssl SQL > SELECT @ciphertext;
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| @ciphertext |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ???8???j<?Ð??J??ȷ?^?0
t.Q?dH4B??I??xtTT{?W?&{??E?}????? ??L?>?c?2?$?D_"gs?"Xg???û;ڞ[zt??I?ʷ?b!?&?j]"8? C?m??2+:?^?f???v?,??P?M?jiE?<{?Nn? ?vы@????K???6?'?G$?y??0?A{?K=]??*??ѹ?????,?ږ?ד?9/QSک^?I϶C???+V
? |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.0007 sec)
--解密数据
MySQL localhost:3350 ssl SQL > SELECT asymmetric_decrypt(@algo, @ciphertext, @priv);
+-----------------------------------------------+
| asymmetric_decrypt(@algo, @ciphertext, @priv) |
+-----------------------------------------------+
| 这是秘密 |
+-----------------------------------------------+
1 row in set (0.0034 sec)
从字符串生成摘要:
MySQL localhost:3350 ssl SQL > SET @dig_type = 'SHA512';
Query OK, 0 rows affected (0.0004 sec)
MySQL localhost:3350 ssl SQL > SET @dig = create_digest(@dig_type, '用于生成摘要的文本');
Query OK, 0 rows affected (0.0003 sec)
将摘要与密钥对一起使用:
MySQL localhost:3350 ssl SQL > SET @sig = asymmetric_sign(@algo, @dig, @priv, @dig_type);
Query OK, 0 rows affected (0.0032 sec)
MySQL localhost:3350 ssl SQL > SET @verf = asymmetric_verify(@algo, @dig, @sig, @pub, @dig_type);
Query OK, 0 rows affected (0.0015 sec)
MySQL localhost:3350 ssl SQL > SELECT @verf;
+-------+
| @verf |
+-------+
| 1 |
+-------+
1 row in set (0.0005 sec)
以上是关于企业版加密的简单示例,感兴趣的读者可以访问官网查看详情。
综上所述,8.0.30的加密功能带来了新的变化,这些变化能够提升MySQL的安全性,如果用户对加密方面有着更为严格需求,建议采用MySQL企业版所提供的组件。
本文分享自 MySQL解决方案工程师 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!