将aes/cbc/pkcs5padding从java转换为php

5sxhfpxr  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(488)

我必须将一个加密的json对象从java匹配到php,但我没有这样做。在stackoverflow上尝试了几乎所有的解决方案,仍然没有成功。
doc说,字段必须通过aes加密的json表示的所有字段的商人想要发送。加密算法必须是aes/cbc/PKCS5P,并且必须使用提供的加密密钥。用于数据加密的初始化向量的长度必须为16字节,等于0。加密字节数组必须编码为base64。
{“addrmatch”:“n}应转换为q8zzcoyhkggpsfxdmdzdobe2r/1ewnfgco2fjzjhtjq=
我有以下代码:

import java.security.InvalidAlgorithmParameterException;
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.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class Utility {
    public static String encode3DSdata(String APISecretMerchant, String JSONobject) throws Throwable {

        // Initialization vector
        byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        // AES Key from the API merchant key
        byte[] key = APISecretMerchant.substring(0, 16).getBytes();
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

        byte[] toEncrypt = JSONobject.getBytes("UTF-8");
        // Encrypt
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encrypted = cipher.doFinal(toEncrypt);
        // Convert to base64
        return DatatypeConverter.printBase64Binary(encrypted);
    }
}

以下是我在php上的代码:

function pkcs5pad($text,$blocksize) {
            $pad = $blocksize - (strlen($text) % $blocksize);
            return $text.str_repeat(chr($pad), $pad);
        }

        function encrypt($data, $key)
        {
            $json = iconv('utf-8', 'utf-8//IGNORE', json_encode($data,JSON_UNESCAPED_SLASHES));
            $padded=pkcs5pad($json,16);
            $encrypted = openssl_encrypt($padded, 'AES-128-CBC', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, self::iv);
            return base64_encode($encrypted);
        }

        const iv = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'; // also tried as "0000000000000000"
        $key='c-MCjRx4X-pD-Lux';
        $data=['addrMatch'=>'N'];
        echo encrypt($data,$key);

我公司生产:bpo0necny+dfrdislycefu8sqhx/4hsr5io+zue4sro=
任何帮助都将不胜感激。

dfddblmv

dfddblmv1#

php代码中有两个问题。
第一:有一个16 x#d 00的固定静脉-这样使用:

$iv = "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0";

第二:使用openssl内置填充(它被命名为pkcs7,但它类似于java的pkcs5)
输出:

encrypt: q8zzcOYHKggpSFXdmdZdObe2R/1EWnFgco2FJzjhtJQ=
expected:q8zzcOYHKggpSFXdmdZdObe2R/1EWnFgco2FJzjhtJQ=

安全警告:代码不安全,因为它使用固定密钥+初始化向量。
代码:

<?php
function encrypt($data, $key)
{
    $iv = "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0";
    $json = iconv('utf-8', 'utf-8//IGNORE', json_encode($data,JSON_UNESCAPED_SLASHES));
    $encrypted = openssl_encrypt($json, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encrypted);
}

$key='c-MCjRx4X-pD-Lux';
$data=['addrMatch'=>'N'];
echo 'encrypt: ' . encrypt($data,$key) . PHP_EOL;
echo 'expected:' . 'q8zzcOYHKggpSFXdmdZdObe2R/1EWnFgco2FJzjhtJQ=' . PHP_EOL;
?>

相关问题