java 实现 mysql AES_ENCRYPT AES_DECRYPT函数的实现

java 实现 mysql AES_ENCRYPT AES_DECRYPT函数的实现


aes加解密就不多说了,网上有不少文章可以参考,关于mysql的AES_ENCRYPT加密方式也有不少文章,因为key的长度限制,大多人采用的方式如下:

   byte[] keyBytes = Arrays.copyOf(strKey.getBytes("ASCII"), 16);
   SecretKey key = new SecretKeySpec(keyBytes, "AES");

这种方式可以实现16 byte以下(包含16byte)的key的加解密问题,但是如果key 的长度超出范围,就会发现这种方式的加解密和mysql的结果不一样了。下面说一下我用的工具类的实现,实际上就是SecretKey的获取的问题

	public 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(UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

留个较完整的demo
数据库测试

set @aeskey:='dc58af43160ddf8cd776379c91cfdef88e31acbede1d56db2d34db534e069d77c0f104f71a9e05c05275b19aa8a88b497495e31412ce8fbbfc80de805efdfb77';
SELECT HEX(AES_ENCRYPT("12345678901",@aeskey))

##  运行结果   27B9F0FD5DEE717F1432970377DF567B

java 的demo,不建议直接打印异常,只做参考

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

public class test {

	public static String aes_encrypt(String password, String strKey) {
		try {
			SecretKey key = generateMySQLAESKey(strKey,"ASCII");
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] cleartext = password.getBytes("UTF-8");
			byte[] ciphertextBytes = cipher.doFinal(cleartext);
			return new String(Hex.encodeHex(ciphertextBytes));

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String aes_decrypt(String content, String aesKey){
		try {
			SecretKey key = generateMySQLAESKey(aesKey,"ASCII");
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] cleartext = Hex.decodeHex(content.toCharArray());
			byte[] ciphertextBytes = cipher.doFinal(cleartext);
			return new String(ciphertextBytes, "UTF-8");

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		}
		return null;
	}

	
	public 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(UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
}

主函数测试

public static void main(String[] args){
		String abc = "12345678901";
		String aeskey = "dc58af43160ddf8cd776379c91cfdef88e31acbede1d56db2d34db534e069d77c0f104f71a9e05c05275b19aa8a88b497495e31412ce8fbbfc80de805efdfb77";
		String a1=aes_encrypt(abc, aeskey);
		System.out.println(a1);
		System.out.println(aes_decrypt(a1, aeskey));
	}

执行结果

27b9f0fd5dee717f1432970377df567b
12345678901

希望对有需要的朋友提供一点帮助

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值