【问题标题】:Convert AES/CBC/PKCS5Padding from Java to PHP将 AES/CBC/PKCS5Padding 从 Java 转换为 PHP
【发布时间】:2021-03-21 00:34:27
【问题描述】:

我必须将加密的 JSON 对象从 Java 匹配到 PHP,但我没有这样做。在stackoverflow上尝试了几乎所有的解决方案,仍然没有运气。

DOC 说字段必须通过商家想要发送的所有字段的 JSON 表示的 AES 加密获得。加密算法必须是 AES/CBC/PKCS5Padding 并且必须使用提供的加密密钥。用于数据加密的初始化向量必须是 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=

任何帮助将不胜感激。

【问题讨论】:

    标签: java php encryption aes


    【解决方案1】:

    您的 PHP 代码中有两个问题。

    首先:有一个 16 x#d 00 的固定 IV - 这样使用它:

    $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;
    ?>
    

    【讨论】:

      猜你喜欢
      • 2020-04-30
      • 2021-09-13
      • 2022-12-02
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-11
      相关资源
      最近更新 更多