java和mysql加密AES通用,及解决在linux下加密结果不一致问题

本文介绍了一种在 Linux 环境下使用 AES 对 MySQL 数据进行加密的方法,并解决了因 SecureRandom 导致的加密结果不一致的问题。通过设置 SecureRandom 的种子为固定值,确保了加密过程的稳定性和加密结果的一致性。
	private static SecretKeySpec generateMySQLAESKey(final String key, final String encoding) {
		try {
			final byte[] finalKey = new byte[16];
			int i = 0;
			for (byte b : key.getBytes(encoding)) {
				finalKey[i++ % 16] ^= b;
			}
			return new SecretKeySpec(finalKey, "AES");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String encryptMysql(String str, String aesKey) {
		try {
			final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			// 一定要用上第三个参数,设置一个随机数种子,否则在linux下某些情况加密的密文不一致
			SecureRandom secureRandom = new SecureRandom();
			secureRandom.setSeed(1L);
			cipher.init(Cipher.ENCRYPT_MODE, generateMySQLAESKey(aesKey, "UTF-8"), secureRandom);
			return Hex.encodeHexString(cipher.doFinal(str.getBytes("UTF-8"))).toUpperCase();
		} catch (Exception e) {
			log.error("encryptMysql error", e);
		}
		return null;
	}

linux环境下加密密文不一致,这个问题导致有时候能和mysql加密匹配,有时候却不行,设置一个随机数种子就可以了

转载于:https://my.oschina.net/u/233090/blog/1822443

SQL Server MySQLAES 加密实现上的差异主要体现在加密算法的默认模式、密钥长度处理、填充方式以及数据编码方式等方面。这些因素会导致在两个数据库中使用相同的明文密钥进行加密时,得到的密文一致。 ### 加密差异的原因分析 1. **加密模式(Block Cipher Mode)** MySQL 的 `AES_ENCRYPT` 默认使用的是 ECB(Electronic Codebook)模式[^1],而 SQL Server 的 AES 加密通常依赖于透明数据加密(TDE),其加密模式为 CBC(Cipher Block Chaining)或类似的更安全模式[^2]。同的加密模式会导致即使使用相同的密钥明文,加密结果同。 2. **密钥长度与派生机制** MySQL 的 `AES_ENCRYPT` 函数会根据提供的密钥字符串自动截断或填充,以适配 AES-128 或 AES-256 的密钥长度要求。例如,若提供的密钥足 32 字节(256 位),则会进行填充;而 SQL Server 在 TDE 中使用的是基于证书的密钥派生机制,密钥由系统自动管理,且通常更符合标准加密规范[^2]。 3. **填充方式(Padding)** AES 是分组加密算法,要求明文长度是块大小(通常为 16 字节)的整数倍。MySQL 默认使用 PKCS#7 填充方式,而 SQL Server 的 TDE 实现可能采用同的填充策略或依赖填充(如在流加密中)。这种差异也会导致加密结果同[^1]。 4. **编码方式** MySQL 中常使用 `HEX()` 函数将二进制加密结果转换为十六进制字符串存储,而 SQL Server 可能直接以二进制格式存储加密数据。这种编码方式的同会影响最终存储内容的表示形式[^4]。 ### 解决方案 若需在 SQL Server MySQL 之间实现一致AES 加密结果,需确保以下几点: - 使用相同的加密算法(如 AES-256)。 - 指定相同的加密模式(如 CBC)。 - 使用相同的填充方式(如 PKCS#7)。 - 使用相同的密钥派生方式(如 PBKDF2)。 - 使用相同的初始向量(IV),在使用 CBC 模式时尤为重要。 - 保证数据编码方式一致(如都使用 HEX 编码或都使用 Base64 编码)。 #### 示例:MySQL 中使用 CBC 模式加密 MySQL 从 5.7 起支持通过 `block_encryption_mode` 设置加密模式,例如设置为 CBC: ```sql SET block_encryption_mode = 'aes-256-cbc'; SELECT HEX(AES_ENCRYPT('Hello World', 'mykey1234567890', 'myiv123456789012')) AS encrypted; ``` 其中 `'mykey1234567890'` 是 16 字节的密钥,`'myiv123456789012'` 是 16 字节的 IV[^1]。 #### 示例:SQL Server 中使用相同参数进行加密 SQL Server 本身直接提供 AES 函数,但可以通过扩展(如 CLR 函数)或调用外部加密库(如 .NET)实现: ```csharp using System; using System.Security.Cryptography; public class AesEncryption { public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv) { using (Aes aes = Aes.Create()) { aes.Key = key; aes.IV = iv; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (var encryptor = aes.CreateEncryptor()) return encryptor.TransformFinalBlock(data, 0, data.Length); } } } ``` ### 总结 SQL Server MySQLAES 加密结果一致,主要是由于加密模式、填充方式、密钥处理编码方式同所导致。要实现一致性,必须在两者中配置相同的加密参数,包括加密模式、填充方式、密钥长度 IV。通过调整 MySQL 的 `block_encryption_mode` 并在 SQL Server 中使用标准加密库,可以实现跨数据库一致加密结果。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值