求助:JAVA加密的数据PHP解密

已经尝试过用php解密,但是对java代码不懂导致解密时连蒙带猜,最终也没有解密出来,懂的帮忙解答一下。
java加密后的密文:iP6nVfCE9Eiw47utJDR6wV6Lhl4xyOgYykub0HUJSZQ=
以下是java的aes加密类,希望能用php解密出来

package com.mk.api.util;

import java.security.Key;
import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

/**
 * AES 加密
 */
public class AES {

    private static final String AESTYPE = "AES";
    private static final String KEY = "Z8LSq0wWwB5v+6YJzurcP463H3F12iZh74fDj4S74oUH4EONkiKb2FmiWUbtFh97GG/c/lbDE47mvw6j94yXxKHOpoqu6zpLKMKPcOoSppcVWb2q34qENBJkudXUh4MWcreondLmLL2UyydtFKuU9Sa5VgY/CzGaVGJABK2ZR94=";

    /**
     * 加密
     * @param content
     * @return
     */
    public static String encrypt(String str) {
        try {
            Key key = generateKey();
            Cipher c = Cipher.getInstance(AESTYPE);
            c.init(Cipher.ENCRYPT_MODE, key);
            byte[] encVal = c.doFinal(str.getBytes());
            String encryptedValue = DatatypeConverter.printBase64Binary(encVal);
            return encryptedValue;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解密
     * @param content
     * @return
     */
    public static String decrypt(String str) {
        try {
            Key key = generateKey();
            Cipher c = Cipher.getInstance(AESTYPE);
            c.init(Cipher.DECRYPT_MODE, key);
            byte[] decordedValue = DatatypeConverter.parseBase64Binary(str);
            byte[] decValue = c.doFinal(decordedValue);
            String decryptedValue = new String(decValue);
            return decryptedValue;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Key generateKey() throws Exception {
        byte[] keyValue = KEY.getBytes("UTF-8");
        MessageDigest sha = MessageDigest.getInstance("SHA-1");
        keyValue = sha.digest(keyValue);
        keyValue = Arrays.copyOf(keyValue, 16);
        Key key = new SecretKeySpec(keyValue, AESTYPE);
        return key;
    }


}
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

算法一定要知其然所以然,很多人对DES、AES的一些细节知识都是一知半解,所以有时候在需要灵活变动的时候往往一头雾水。

<?php

$encrypted = 'iP6nVfCE9Eiw47utJDR6wV6Lhl4xyOgYykub0HUJSZQ=';
// 从密文观测,是一个base64输出的密文,需要base64_decode
$encrypted = base64_decode($encrypted);

// 1 对照java,对密钥进行了一次sha1
// 2 AES算法的密钥必须是16的倍数,所以需要截取
$key = 'Z8LSq0wWwB5v+6YJzurcP463H3F12iZh74fDj4S74oUH4EONkiKb2FmiWUbtFh97GG/c/lbDE47mvw6j94yXxKHOpoqu6zpLKMKPcOoSppcVWb2q34qENBJkudXUh4MWcreondLmLL2UyydtFKuU9Sa5VgY/CzGaVGJABK2ZR94=';
$key = substr(sha1($key, true), 0, 16);

// java的AES加密,默认是 AES / ECB / PKCS5Padding 模式
// 其实我也不懂java,我是观测到java代码没有设置iv向量,AES算法中,ECB模式才是无需向量的
$str = openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_NO_PADDING);
$str = unPkcsPadding($str);
var_dump($str);
// 172592;26;20220720100328

/**
 * 去填充
 *
 * @param $str
 * @return string
 */
function unPkcsPadding($str)
{
    $pad = ord($str[strlen($str) - 1]);
    if ($pad > strlen($str)) {
        return false;
    }
    return rtrim(substr($str, 0, -1 * $pad));
}
1年前 评论
win27149 (楼主) 1年前
讨论数量: 9

算法一定要知其然所以然,很多人对DES、AES的一些细节知识都是一知半解,所以有时候在需要灵活变动的时候往往一头雾水。

<?php

$encrypted = 'iP6nVfCE9Eiw47utJDR6wV6Lhl4xyOgYykub0HUJSZQ=';
// 从密文观测,是一个base64输出的密文,需要base64_decode
$encrypted = base64_decode($encrypted);

// 1 对照java,对密钥进行了一次sha1
// 2 AES算法的密钥必须是16的倍数,所以需要截取
$key = 'Z8LSq0wWwB5v+6YJzurcP463H3F12iZh74fDj4S74oUH4EONkiKb2FmiWUbtFh97GG/c/lbDE47mvw6j94yXxKHOpoqu6zpLKMKPcOoSppcVWb2q34qENBJkudXUh4MWcreondLmLL2UyydtFKuU9Sa5VgY/CzGaVGJABK2ZR94=';
$key = substr(sha1($key, true), 0, 16);

// java的AES加密,默认是 AES / ECB / PKCS5Padding 模式
// 其实我也不懂java,我是观测到java代码没有设置iv向量,AES算法中,ECB模式才是无需向量的
$str = openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_NO_PADDING);
$str = unPkcsPadding($str);
var_dump($str);
// 172592;26;20220720100328

/**
 * 去填充
 *
 * @param $str
 * @return string
 */
function unPkcsPadding($str)
{
    $pad = ord($str[strlen($str) - 1]);
    if ($pad > strlen($str)) {
        return false;
    }
    return rtrim(substr($str, 0, -1 * $pad));
}
1年前 评论
win27149 (楼主) 1年前

看样子像 AES 加密,密钥需要用sha1加密一次再使用

1年前 评论
win27149 (楼主) 1年前
deatil (作者) 1年前
pndx

之前碰到过我的情况是要处理偏移才行。

1年前 评论
win27149 (楼主) 1年前
pndx (作者) 1年前

算法一定要知其然所以然,很多人对DES、AES的一些细节知识都是一知半解,所以有时候在需要灵活变动的时候往往一头雾水。

<?php

$encrypted = 'iP6nVfCE9Eiw47utJDR6wV6Lhl4xyOgYykub0HUJSZQ=';
// 从密文观测,是一个base64输出的密文,需要base64_decode
$encrypted = base64_decode($encrypted);

// 1 对照java,对密钥进行了一次sha1
// 2 AES算法的密钥必须是16的倍数,所以需要截取
$key = 'Z8LSq0wWwB5v+6YJzurcP463H3F12iZh74fDj4S74oUH4EONkiKb2FmiWUbtFh97GG/c/lbDE47mvw6j94yXxKHOpoqu6zpLKMKPcOoSppcVWb2q34qENBJkudXUh4MWcreondLmLL2UyydtFKuU9Sa5VgY/CzGaVGJABK2ZR94=';
$key = substr(sha1($key, true), 0, 16);

// java的AES加密,默认是 AES / ECB / PKCS5Padding 模式
// 其实我也不懂java,我是观测到java代码没有设置iv向量,AES算法中,ECB模式才是无需向量的
$str = openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_NO_PADDING);
$str = unPkcsPadding($str);
var_dump($str);
// 172592;26;20220720100328

/**
 * 去填充
 *
 * @param $str
 * @return string
 */
function unPkcsPadding($str)
{
    $pad = ord($str[strlen($str) - 1]);
    if ($pad > strlen($str)) {
        return false;
    }
    return rtrim(substr($str, 0, -1 * $pad));
}
1年前 评论
win27149 (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!