java的aes解密方法转换成php7类?

zhao
  • 2
四川新手上路,请多包涵

java的aes解密方法转换成php7解密类

网上搜索了好多都不对

相关代码

package cn.com.datatalk.openapi.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class DecryptUtil implements Serializable {
    private static final long serialVersionUID = 1L;

    private SecretKey secretKey;

    private transient Cipher cipher;

    private final transient Lock lock = new ReentrantLock();

    private static final  Map<String, byte[]> keyMap = new HashMap<>();


    private DecryptUtil(byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException {
        SecretKey sctKey = new SecretKeySpec(key, "AES");
        init("AES", sctKey);
    }
    /**
     * 解密方法
     * @param privateKey privateKey
     * @param content 密文
     * @return 应返回Json格式
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static JSONObject decryptStr(String privateKey, String content) {
        byte[] key = DecryptUtil.getKey(privateKey);
        DecryptUtil decrypt = null;
        try {
            decrypt = new DecryptUtil(key);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            log.error(e.getMessage());
        }

        if (decrypt.decryptStr(content) != null){
            return JSONObject.parseObject(decrypt.decryptStr(content));
        }else {
            return new JSONObject();
        }

    }

    private static byte[] getKey(String privateKey) {
        if (keyMap.containsKey(privateKey)) {
            return keyMap.get(privateKey);
        } else {
            try {
                //返回 KeyGenerator对象,该对象为指定的算法生成密钥。
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                //重新设置此随机对象的种子
                secureRandom.setSeed(privateKey.getBytes());
                //使用指定的参数集和用户提供的随机源初始化此密钥生成器
                kgen.init(128, secureRandom);
                SecretKey secretKey = kgen.generateKey();
                //以主编码格式返回密钥,如果此密钥不支持编码,则返回null。
                byte[] enCodeFormat = secretKey.getEncoded();
                keyMap.put(privateKey, enCodeFormat);
                return enCodeFormat;
            } catch (NoSuchAlgorithmException e) {
                log.error(e.getMessage());
            }
        }
        return new byte[0];
    }



    private DecryptUtil init(String algorithm, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException {
        if (algorithm == null || "".equals(algorithm)) {
            return null;
        }
        this.secretKey = key;
        this.cipher = Cipher.getInstance(algorithm);
        return this;
    }

    public static byte[] decodeHex(CharSequence hexData) {
        if (hexData == null || hexData.length() == 0) {
            return new byte[0];
        }
        final int len = hexData.length();

        if ((len & 0x01) != 0) {
            throw new RuntimeException("Odd number of characters.");
        }

        final byte[] out = new byte[len >> 1];
        for (int i = 0, j = 0; j < len; i++) {
            int f = toDigit(hexData.charAt(j)) << 4;
            j++;
            f = f | toDigit(hexData.charAt(j));
            j++;
            out[i] = (byte) (f & 0xFF);
        }
        return out;
    }

    private static int toDigit(char ch) {
        int digit = Character.digit(ch, 16);
        if (digit < 0) {
            throw new RuntimeException("Illegal hexadecimal character {} at index {}");
        } else {
            return digit;
        }
    }

    private byte[] decrypt(String data) {
        byte[] encryptData = decodeHex(data);
        final int blockSize;
        final byte[] decryptData;

        lock.lock();
        try {
            final Cipher cph = initCipher(Cipher.DECRYPT_MODE);
            blockSize = cph.getBlockSize();
            decryptData = cph.doFinal(encryptData);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
        return removePadding(decryptData, blockSize);
    }

    private String decryptStr(String data) {
        return new String(decrypt(data),StandardCharsets.UTF_8);
    }

    private Cipher initCipher(int mode) throws InvalidKeyException {
        final Cipher cph = this.cipher;
        cph.init(mode, secretKey);
        return cph;
    }

    private static byte[] removePadding(byte[] data, int blockSize)  {
        if (blockSize > 0) {
            final int length = data.length;
            final int remainLength = length % blockSize;
            if (remainLength == 0) {
                // 解码后的数据正好是块大小的整数倍,说明可能存在补0的情况,去掉末尾所有的0
                int i = length - 1;
                while (i >= 0 && 0 == data[i]) {
                    i--;
                }
                return resize(data, i + 1);
            }
        }
        return data;
    }

    private static byte[] resize(byte[] bytes, int newSize) {
        if (newSize < 0) {
            return bytes;
        } else {
            byte[] newArray = new byte[newSize];
            if (newSize > 0 && !(bytes == null || bytes.length == 0)) {
                System.arraycopy(bytes, 0, newArray, 0, Math.min(bytes.length, newSize));
            }
            return newArray;
        }
    }
}

希望各位帮忙看看

回复
阅读 362
1 个回答
zhao
  • 2
四川新手上路,请多包涵

自问自答一番

/**
     * hexToStr method
     * @param $hex
     * @return string
     * @author     :lance
     * @description:{将hex格式字符串还原为字符串格式}
     */
function hexToStr($hex)
    {
        $string = '';
        for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
            $string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
        }
        return $string;
    }

$data ='4ce438a00d6faf4e09869fd1c1641524655a1ee';
//生成
$soureKey ='xxxxx';
$newKey = substr(openssl_digest(openssl_digest($soureKey, 'sha1', true), 'sha1', true), 0, 16);
//将原来hex格式加密内容转换字符串
$enByte = $this->hexToStr($data);
//进行解密操作
$dec = openssl_decrypt($enByte, 'AES-128-ECB', $key, OPENSSL_RAW_DATA, '');
echo $dec;

参考
https://segmentfault.com/q/10...

宣传栏