MySQL 8.0的新特性1——加密函数
随着数据安全意识提高,数据库加密功能变得越来越重要。MySQL 8.0在加密方面提供了更多的功能和改进,包括更强大的加密算法、安全的密码存储方式以及数据传输加密等。本章将详细介绍MySQL 8.0中的加密函数及其用法。
MySQL加密函数概述
MySQL提供了多种加密函数,用于数据的哈希计算、加密和解密操作。这些函数可以帮助开发者保护敏感数据,如用户密码、信用卡信息等。MySQL 8.0中支持的主要加密函数包括:
- MD5加密函数
- SHA加密函数(SHA-1)
- SHA2加密函数(SHA-224、SHA-256、SHA-384、SHA-512)
- AES加密和解密函数
- RSA加密和解密函数(MySQL 8.0新增)
- 其他加密相关函数
MD5加密函数
MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,可以产生一个128位(16字节)的散列值(哈希值)。虽然MD5在安全性方面已经不再被推荐用于敏感数据保护,但在一些非安全场景下仍然可以使用。
函数 | 描述 | 示例 |
---|---|---|
MD5(str) | 计算字符串str的MD5散列值,返回32位十六进制字符串 | MD5('hello') = '5d41402abc4b2a76b9719d911017c592' |
MD5函数示例
-- 计算字符串的MD5哈希值
SELECT MD5('hello') AS md5_hash;
-- 使用MD5存储密码(注意:现代应用中不推荐使用MD5存储密码)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password_hash VARCHAR(32) NOT NULL
);
-- 插入用户数据时计算密码的MD5哈希
INSERT INTO users (username, password_hash)
VALUES ('john', MD5('secret123'));
-- 验证用户密码
SELECT * FROM users
WHERE username = 'john' AND password_hash = MD5('secret123');
-- 使用MD5检查文件完整性
SELECT MD5(CONCAT(column1, column2, column3)) AS record_hash FROM data_table;
-- 生成简单的随机令牌
SELECT MD5(CONCAT(NOW(), RAND())) AS random_token;
注意:MD5算法在安全领域已经被证明存在漏洞,不应该用于存储敏感数据如用户密码。对于安全要求较高的应用,建议使用SHA256或更高级的哈希算法,并结合盐值(salt)来增强安全性。
SHA加密函数(SHA-1)
SHA(Secure Hash Algorithm)是一系列密码散列函数的统称。SHA-1是其中的一个版本,可以产生一个160位(20字节)的散列值。与MD5类似,SHA-1在安全性方面也存在一些问题,在某些场景下可能不再足够安全。
函数 | 描述 | 示例 |
---|---|---|
SHA(str) | 计算字符串str的SHA-1散列值,返回40位十六进制字符串 | SHA('hello') = 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d' |
SHA1(str) | SHA()的同义词,计算SHA-1散列值 | SHA1('hello') = 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d' |
SHA函数示例
-- 计算字符串的SHA-1哈希值
SELECT SHA('hello') AS sha1_hash;
SELECT SHA1('hello') AS sha1_hash;
-- 使用SHA-1存储密码(注意:现代应用中推荐使用更安全的算法)
CREATE TABLE secure_users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password_hash VARCHAR(40) NOT NULL
);
-- 插入用户数据时计算密码的SHA-1哈希
INSERT INTO secure_users (username, password_hash)
VALUES ('mary', SHA('secure456'));
-- 验证用户密码
SELECT * FROM secure_users
WHERE username = 'mary' AND password_hash = SHA('secure456');
-- 比较MD5和SHA-1哈希长度
SELECT
LENGTH(MD5('hello')) AS md5_length,
LENGTH(SHA('hello')) AS sha1_length;
注意:SHA-1算法在2017年被正式宣布不再安全,存在碰撞攻击的风险。对于需要高安全性的应用,建议使用SHA-2系列算法如SHA-256或SHA-512。
SHA2加密函数
SHA2是SHA-2系列加密算法的统称,包括SHA-224、SHA-256、SHA-384和SHA-512等多种变体。这些算法提供了比MD5和SHA-1更高的安全性,是现代应用中推荐使用的哈希算法。
函数 | 描述 | 示例 |
---|---|---|
SHA2(str, hash_length) | 计算字符串str的SHA-2哈希值,hash_length指定哈希长度(224、256、384、512) | SHA2('hello', 256) = '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824' |
SHA2函数示例
-- 计算字符串的不同长度的SHA-2哈希值
SELECT
SHA2('hello', 224) AS sha224_hash,
SHA2('hello', 256) AS sha256_hash,
SHA2('hello', 384) AS sha384_hash,
SHA2('hello', 512) AS sha512_hash;
-- 查看不同SHA-2哈希值的长度
SELECT
LENGTH(SHA2('hello', 224)) AS sha224_length,
LENGTH(SHA2('hello', 256)) AS sha256_length,
LENGTH(SHA2('hello', 384)) AS sha384_length,
LENGTH(SHA2('hello', 512)) AS sha512_length;
-- 使用SHA-256和盐值存储密码(推荐的安全做法)
CREATE TABLE secure_users_with_salt (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password_salt VARCHAR(32) NOT NULL,
password_hash VARCHAR(64) NOT NULL
);
-- 生成随机盐值并插入用户数据
INSERT INTO secure_users_with_salt (username, password_salt, password_hash)
VALUES (
'bob',
SUBSTRING(MD5(RAND()), 1, 16), -- 生成16位随机盐值
SHA2(CONCAT('password789', SUBSTRING(MD5(RAND()), 1, 16)), 256) -- 密码加盐哈希
);
-- 验证用户密码(需要先获取盐值)
SET @username = 'bob';
SET @input_password = 'password789';
SELECT suws.*
FROM secure_users_with_salt suws
WHERE suws.username = @username
AND suws.password_hash = SHA2(CONCAT(@input_password, suws.password_salt), 256);
推荐做法:在存储用户密码时,应使用SHA-256或SHA-512等强哈希算法,并结合随机生成的盐值(salt)。盐值应足够长且随机,并且对每个用户使用不同的盐值。这样即使两个用户使用相同的密码,存储的哈希值也会不同,增加了安全性。
AES加密和解密函数
AES(Advanced Encryption Standard)是一种对称加密算法,广泛应用于数据加密。MySQL提供了AES_ENCRYPT()和AES_DECRYPT()函数用于数据的加密和解密。
函数 | 描述 | 示例 |
---|---|---|
AES_ENCRYPT(str, key_str) | 使用key_str作为密钥加密字符串str,返回二进制数据 | AES_ENCRYPT('敏感信息', 'secret_key') |
AES_DECRYPT(crypt_str, key_str) | 使用key_str作为密钥解密加密字符串crypt_str | AES_DECRYPT(encrypted_data, 'secret_key') |
AES加密和解密函数示例
-- 加密敏感数据
SELECT AES_ENCRYPT('敏感信息', 'encryption_key') AS encrypted_data;
-- 加密并转换为十六进制字符串以便存储
SELECT HEX(AES_ENCRYPT('敏感信息', 'encryption_key')) AS hex_encrypted_data;
-- 创建包含加密列的表
CREATE TABLE sensitive_data (
id INT AUTO_INCREMENT PRIMARY KEY,
encrypted_info VARBINARY(1000), -- 用于存储加密的二进制数据
hex_encrypted_info VARCHAR(2000) -- 用于存储十六进制编码的加密数据
);
-- 插入加密数据
INSERT INTO sensitive_data (encrypted_info, hex_encrypted_info)
VALUES (
AES_ENCRYPT('信用卡号:1234-5678-9012-3456', 'my_secure_key'),
HEX(AES_ENCRYPT('信用卡号:1234-5678-9012-3456', 'my_secure_key'))
);
-- 解密数据
SELECT
AES_DECRYPT(encrypted_info, 'my_secure_key') AS decrypted_info,
AES_DECRYPT(UNHEX(hex_encrypted_info), 'my_secure_key') AS decrypted_hex_info
FROM sensitive_data;
-- 结合其他函数使用AES加密
SELECT
id,
AES_DECRYPT(encrypted_info, 'my_secure_key') AS customer_info
FROM sensitive_data
WHERE AES_DECRYPT(encrypted_info, 'my_secure_key') LIKE '%信用卡%';
MySQL 8.0中的加密增强
MySQL 8.0在加密方面提供了多项增强功能:
1. 加密连接默认启用
MySQL 8.0默认要求加密连接,提高了数据传输的安全性。可以通过以下系统变量控制加密连接设置:
require_secure_transport
:控制是否要求加密连接tls_version
:指定支持的TLS版本ssl_ca
、ssl_cert
、ssl_key
:指定SSL证书相关文件
2. 支持更多加密算法
MySQL 8.0支持更多的加密算法,包括:
- RSA加密和解密函数
- 更强大的随机数生成函数
- 支持更多的哈希算法
3. 数据字典加密
MySQL 8.0支持对数据字典进行加密,保护存储在数据字典中的敏感信息。
4. 密钥轮换支持
MySQL 8.0提供了密钥轮换机制,支持定期更换加密密钥,提高数据安全性。
MySQL 8.0加密功能示例
-- 查看MySQL加密相关的系统变量
SHOW VARIABLES LIKE '%ssl%';
SHOW VARIABLES LIKE '%tls%';
-- 检查当前连接是否使用加密
SHOW STATUS LIKE 'Ssl_cipher';
-- 使用RSA加密(MySQL 8.0)
-- 首先需要生成RSA密钥对
-- 服务器端:
INSTALL PLUGIN rsa SOURCE 'file:///path/to/rsa.so';
-- 或者在配置文件中启用
-- 生成RSA密钥对
SELECT * FROM performance_schema.keyring_keys;
-- 使用加密函数进行数据完整性验证
SELECT
data_column,
MD5(data_column) AS md5_checksum,
SHA2(data_column, 256) AS sha256_checksum
FROM data_table;
-- 创建一个视图,自动解密敏感数据
CREATE VIEW decrypted_sensitive_data AS
SELECT
id,
AES_DECRYPT(encrypted_info, 'my_secure_key') AS decrypted_info
FROM sensitive_data;
安全最佳实践:在使用MySQL加密功能时,应注意以下几点:
- 不要在数据库中明文存储敏感信息,如密码、信用卡号等
- 使用强加密算法(SHA-256或更高)结合随机盐值存储密码
- 加密密钥应安全存储,避免硬编码在应用程序中
- 定期轮换加密密钥
- 使用SSL/TLS加密客户端和服务器之间的连接
- 遵循最小权限原则,限制对加密数据的访问