微店-加解密-PHP代码实现

这段代码展示了PHP和Java中使用AES-128-CBC模式进行加密和解密的方法,结合了PKCS7补位以确保数据完整。加密和解密过程涉及到字节操作、Base64编码以及特定的密钥和初始化向量(IV)处理。
摘要由CSDN通过智能技术生成
PHP 加密处理代码
	public static function encrypt($key, $data) {
        try {
            // 获取当前加密内容字节数组
            $textBytes = getBytes($data);
            // 根据加密内容进行补位
            $padBytes = PKCS7Encoder::encode(count($textBytes));
            // 合并补位数据
            $data_message = array_merge($textBytes, $padBytes);
            // 转成字节字符串给与openssl_encrypt进行加密
            $data_message = vsprintf(str_repeat('%c', count($data_message)), $data_message);
            // 处理key值
            $keys = self::string2Byte($key);
            $keys = base64_encode(vsprintf(str_repeat('%c', count($keys)), $keys));
            // 根据key值获取iv值,偏移16位 decodeBase64方法需要搬照Java对应的decodeBase64方法
            $iv = array_slice(self::decodeBase64($key), 0, 16);
            // 处理iv值转成字符串
            $iv = base64_encode(vsprintf(str_repeat('%c', count($iv)), $iv));
            // 加密数据 返回字节码
            $encrypt_message = openssl_encrypt(
                $data_message,
                "aes-128-cbc",
                base64_decode($keys),
                OPENSSL_NO_PADDING,
                base64_decode($iv)
            );
            // 处理成字节数组
            $encrypt_message = getBytes($encrypt_message);
            // 转成字节字符串,出现乱码需base64返回数据
            $encrypt_message = base64_encode(vsprintf(str_repeat('%c', count($encrypt_message)), $encrypt_message));
            return  $encrypt_message;
        } catch (\Exception $e) {
            throw new CustomApiException('加密处理失败');
        }
    }
PHP 解密处理方法
	public static function decrypt($string, $key) {
        try {
            // 处理key值
            $keys = self::string2Byte($key);
            $keys = vsprintf(str_repeat('%c', count($keys)), $keys);
            // base64转换成字节再转化成字节数组
            $desc = getBytes(base64_decode($string));
            // 字节数组转字符串
            $decrypt = vsprintf(str_repeat('%c', count($desc)), $desc);
            // 根据key值获取iv值,偏移16位
            $aesKey = array_slice(self::decodeBase64($key), 0, 16);
            // 处理iv值转成字符串
            $iv = base64_encode(vsprintf(str_repeat('%c', count($aesKey)), $aesKey));
            // 解密返回字节字符串
            $decrypt_message = openssl_decrypt(
                $decrypt,
                "aes-128-cbc",
                $keys,
                OPENSSL_NO_PADDING,
                base64_decode($iv)
            );
            // 获取当前转义的字符串转字节数组
            $decrypt_message = getBytes($decrypt_message);
            // 去除pkcs7补位数据
            $decrypt_message = PKCS7Encoder::decode($decrypt_message);
            // 字节数组转字符串
            $decrypt_message = vsprintf(str_repeat('%c', count($decrypt_message)), $decrypt_message);
            return $decrypt_message;
        } catch (\Exception $e) {
            writeErrLogs('解密处理失败:', $e);
            throw new CustomApiException('解密处理失败');
        }
    }
Java加密方法
	public static String encrypt(String key, String data) {
        try {
            ByteGroup byteCollector = new ByteGroup();
            byte[] textBytes = data.getBytes(CHARSET);
            byteCollector.addBytes(textBytes);
            byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
            byteCollector.addBytes(padBytes);
            byte[] unencrypted = byteCollector.toBytes();
            byte[] aesKey = WdBase64.decodeBase64(key);
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(string2Byte(key), "AES");
            IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
            cipher.init(1, keySpec, iv);
            byte[] encrypted = cipher.doFinal(unencrypted);
            return WdBase64.encodeBase64String(encrypted);
        } catch (Throwable var11) {
            throw var11;
        }
    }
Java解密方法
	public static String decrypt(String key, String data) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            byte[] aesKey = WdBase64.decodeBase64(key);
            SecretKeySpec key_spec = new SecretKeySpec(string2Byte(key), "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
            cipher.init(2, key_spec, iv);
            byte[] encrypted = WdBase64.decodeBase64(data);
            byte[] original = cipher.doFinal(encrypted);
            byte[] bytes = PKCS7Encoder.decode(original);
            return new String(bytes, CHARSET);
        } catch (Throwable var9) {
            throw var9;
        }
    }
PHP封装方法
	// 替换数组内容类似Java的System.arraycopy()方法
    function  arrayCopy($src = [],  $srcPos = 0, $dest = [], $destPos = 0, $length = 0)
    {
        $src = array_slice($src, $srcPos, $length);
        $length_end = $destPos + $length;
        for ($i= $destPos; $i< $length_end; $i++) {
            $dest[$i] = $src[$i-$destPos];
        }
        unset($value);
        return $dest;
    }
    
	// 将字符串转换成字节数组
    function  getBytes($string)
    {
        $bytes = array();
        for($i = 0; $i < strlen($string); $i++){    //遍历每一个字符 用ord函数把它们拼接成一个php数组
            if(ord($string[$i]) >= 128){
                $byte = ord($string[$i]) - 256;
            }else{
                $byte = ord($string[$i]);
            }
            $bytes[] = $byte;
        }
        return $bytes;
    }
    
	// 转字节码
    function  toByte($num)
    {
        $num=decbin($num);    // 转2进制
        $num=substr($num,-8); //取后8位
        $sign= $num[0]; //获取高位符
        if($sign==1 && strlen($num) == 8) { //高位是1 代表是负数 ,则要减去256
            return bindec($num)-256;
        }
        return bindec($num);
    }

    /**
     * 处理成16字节数组
     * @param $str
     * @return array
     */
    public static function string2Byte($str) {
        $result = [];
        $count = strlen($str) / 2;
        for($i = 0; $i < $count; ++$i) {
            $b = ((self::getStrIndex($str[2 * $i]) & 15) << 4 | self::getStrIndex($str[2 * $i + 1]) & 15);
            $result[$i] = $b;
        }
        return $result;
    }

    /**
     * 获取当前字节下标
     * @param $c
     * @return int
     */
    public static function getStrIndex($c) {
        return $c > '9' ? 10 + ($c - 97) : $c - 48;
    }

PKCS7
class PKCS7Encoder
{
    private static $BLOCK_SIZE = 32;
    private static $CHARSET = "utf-8";

    /**
     * 进行数据补位
     * @param $count
     * @return array
     */
    public static function encode($count) {
        $amountToPad = self::$BLOCK_SIZE - $count % self::$BLOCK_SIZE;
        if ($amountToPad == 0) {
            $amountToPad = self::$BLOCK_SIZE;
        }

        $tmp = [];
        for ($index = 0; $index < $amountToPad; ++$index) {
            $tmp[] = $amountToPad;
        }
        return $tmp;
    }

    /**
     * 去除数组补位数据
     * @param $decrypted
     * @return array
     */
    public static function decode($decrypted) {
        $pad = $decrypted[count($decrypted) - 1];
        if ($pad < 1 || $pad > 32) {
            $pad = 0;
        }
        return array_slice($decrypted, 0, count($decrypted) - $pad);
    }
}
示例代码
	$key = "11111111111111111111111111111111";//TODO 密钥,必须是32位
    $data = "你知道跑是啊实打实的阿斯顿阿斯顿阿萨的";//TODO 要加密的数据
     // Java加密过后的信息
    $encrypt_message = 'qotHLbzsDXKDBW1xzgvp7FjLuj/u+3VFzii+ebCTAa4NJJlsM7sFo7NpLKiIg4935p0kFJNjMNHpaPKFpivjiQ==';
    $b = [
       '加密数据:' => AESUtils::encrypt($key, $data),
       '解密数据:' => AESUtils::decrypt($encrypt_message, $key)
    ];
    return $b;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值