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加密,但是一旦加密文本比密钥要长时,加密后的文本就不一样了,当然解密也是不互通的,这两种加密方式根本就不一样,要注意。

posted @ 2023-03-22 17:18  阿弥陀佛呵呵哒  阅读(300)  评论(0)    收藏  举报