aLoNe.Adams.K

独孤圣人的技术小站

AES中Java加密PHP解密的坑。。。

今天需要对接一个java系统中的接口,对方使用了AES加密,根据对方描述基本可以确定对方用的是AES-ECB-128的加密方式,然后使用PKCS5的对齐方式。
我方需要使用openssl_decrypt进行解密,但是在这个过程中死活都无法进行解密。
最后用了一个很奇特的方式进行解密了。。。
先看下java的代码吧:

public static String encrypt(String content, String password) {
    try {
        String ENCRYPT_CHARSET = "UTF-8";
        Security.addProvider(new sun.security.provider.Sun());
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", new sun.security.provider.Sun());
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        secureRandom.setSeed(password.getBytes());
        kgen.init(128, secureRandom);
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES"); // 创建密码器
        byte[] byteContent = content.getBytes(ENCRYPT_CHARSET);
        cipher.init(Cipher.ENCRYPT_MODE, key); // 初始化
        byte[] result = cipher.doFinal(byteContent);
        if (result != null && result.length > 0) {
            /*
                * 注意:
                * return new String(result,ENCRYPT_CHARSET);
                * 会出现javax.crypto.IllegalBlockSizeException:
                * Input length must be multiple of 16 when decrypting with padded cipher
                * 加密后的byte数组是不能强制转换成字符串的,
                * 字符串和byte数组在这种情况下不是互逆的;
                * 需要将二进制数据转换成十六进制表示
                */
            return parseByte2HexStr(result);
        }
    } catch(NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch(NoSuchPaddingException e) {
        e.printStackTrace();
    } catch(InvalidKeyException e) {
        e.printStackTrace();
    } catch(UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch(IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch(BadPaddingException e) {
        e.printStackTrace();
    }
    return null;
}

以上可以看出,java使用了aes加密,然后将加密后的二进制数据转换成了十六进制字符串;
然后再看下我方的解密代码吧。。。

    $userObj=JAVA_SECRETTEXT;
    $userObj=hex2bin($userObj);
    $appkey=substr(openssl_digest(openssl_digest($appkey, 'sha1', true), 'sha1', true), 0, 16);
    $deData=openssl_decrypt($userObj, 'aes-128-ecb',$appkey, OPENSSL_RAW_DATA , '');

这里注意一下$appkey这行的代码,对解密秘钥进行了2次openssl_digest计算,也就是2次的sha1信息摘要计算,然后再取前16位字符串,就可以正常解密了。。

简直无语。。。。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注