java和C++用AES加密数据

项目中需要和C++做数据交互,所有的数据都是使用AES加密,然后base64编码的,现在把代码记录下来下次好参考:

/**
     * 功能描述: 解密
     *
     * @param:
     * @return:
     * @auther: PC_gongyiyang
     * @date: 2018/11/1 17:25
     */
    public static String decrypt(String key, String encrypted) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            IvParameterSpec iv = new IvParameterSpec(new byte[cipher.getBlockSize()]);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] result = Base64.decodeBase64(encrypted);
            byte[] original = cipher.doFinal(result);
            return new String(original);
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        return null;
    }

    /**
     * 功能描述: 加密
     *
     * @param:
     * @return:
     * @auther: PC_gongyiyang
     * @date: 2018/11/1 17:26
     */
    public static byte[] encrypt(String key, String value) {
        try {
            Integer length = 16;
            Integer count = value.getBytes().length;
            Integer residue = count % length;
            if (residue != 0) {
                Integer add = length - residue;
                for (int i = 0; i < add; i++) {
                    value = value + '\0';
                }
            }
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            IvParameterSpec iv = new IvParameterSpec(new byte[cipher.getBlockSize()]);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.encodeBase64(encrypted);
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        return new byte[0];
    }

C++那边如果没有设置的话默认的填充模式应该是NoPadding;nopadding的数据都是16个字节,必须是16的整数倍;所以在字符不足16的整数倍是用'\0'来填充,'\0'在C++里面是null默认不会被解析;

还有关于iv偏移量的问题;C++默认的偏移量应该是16个'\0';就是16位,java也可以设置16个字符:

char[] ivChar = new char[]{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',};

用16个字符手动设置偏移量也是没问题的;

另外在加密数据传输给C++的时候尽量使用byte原始数据,因为java的byte和string互相转化时可能会涉及到编码问题导致数据发生变化;


版权声明:本文为sinat_21184471原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。