Java AES加解密和Postgresql互通
Postgresql用的加解密函数如下:
select encode(encrypt('12345678901234560','0123456789ABHAEQ','aes-cbc/pad:pkcs'),'hex');
加密后使用16进制转为字符串,对应的java加密代码如下:
public static String encrypt_hex(String input, String key) { try { var ivBytes = new byte[16]; var ivParameterSpec = new IvParameterSpec(ivBytes); SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec); var res = cipher.doFinal(input.getBytes()); return Hex.encodeHexString(res); } catch (Exception e) { log.warn("加密失败::" + input); } return null; }
postgresql官方文档上说明了加密有两个函数(encrypt和encrypt_iv),一个带有iv参数,一个不带有iv参数:

所以这里java实现直接创建一个空的16位的iv数组即可,如果不加这个参数,java的实现是随机一个向量参数,所以加密后每次都不一样。
pg解密函数如下:
select decrypt(decode('f236bcf3025f9c8b8b2875a16510379c0f893f8dca249786310024efe7ba1841','hex'),'0123456789ABHAEQ','aes-cbc');
对应的java解密代码如下:
public static String decrypt_hex(String input, String key) { try { var ivBytes = new byte[16]; var ivParameterSpec = new IvParameterSpec(ivBytes); var bytes = Hex.decodeHex(input); var keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); var cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); byte[] original = cipher.doFinal(bytes); return new String(original); } catch (Exception ex) { log.warn("解密失败::" + input); } return null; }
一般情况下,多数用的是加密后直接再Base64一下存储,pg语句可用改为这样:
select encode(encrypt('12345678901234560','0123456789ABHAEQ','aes-cbc/pad:pkcs'),'base64'); select decrypt(decode('f236bcf3025f9c8b8b2875a16510379c0f893f8dca249786310024efe7ba1841','base64'),'0123456789ABHAEQ','aes-cbc');
对应的java代码只需要修改参数input转换为byte数组的方法即可,完整代码就不重复贴了:
Base64.getDecoder().decode(input);
网上看过一些相似的代码,pg使用的是aes-cbc加密,java可以使用aes-ecb加密,但是一旦加密文本比密钥要长时,加密后的文本就不一样了,当然解密也是不互通的,这两种加密方式根本就不一样,要注意。

浙公网安备 33010602011771号