首页 > 解决方案 > 将加密脚本 AES/CBC/PKCS5PADDING Java 转换为 php

问题描述

在尝试了我在互联网上找到的每个代码 2 周后,我寻求帮助......

我必须将 java 脚本转换为 php

我需要你的帮助来指导我找到解决方案

这里是类的代码

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;

public class DirectLinkCryption {

    private static final String ALGORITHM = "AES";

    private static final String UTF_8 = "UTF-8";

    /**
     * AES encryption of the data with Cipher Block Chaining (CBC) and padding to fill up the empty bytes.
     */
    private static final String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5PADDING";

    private IvParameterSpec ivParameterSpec;

    public DirectLinkCryption() {
        initIvParameterSpec();
    }

    public String getEncryptedParameter(String parameter, String password) {
        try {
            Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password), this.ivParameterSpec);

            return Base64.getUrlEncoder().encodeToString(cipher.doFinal(parameter.getBytes()));
        } catch (Exception e) {
            Logger.getRootLogger().error(String.format("Could not encrypt parameter '%s'!", parameter));
            Logger.getRootLogger().error(e, e);
            return "";
        }
    }

    public static String getDecryptedParameter(String url, String password, String initializationVector) {
        try {
            Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password), new IvParameterSpec(Base64.getUrlDecoder().decode(initializationVector)));

            return new String(cipher.doFinal(Base64.getUrlDecoder().decode(url)));
        } catch (Exception e) {
            Logger.getRootLogger().error(String.format("Could not decrypt url '%s' with AES 128", url));
            Logger.getRootLogger().error(e, e);
            return "";
        }
    }

    private void initIvParameterSpec() {
        byte[] ivBytes = new byte[16];
        (new SecureRandom()).nextBytes(ivBytes);

        this.ivParameterSpec = new IvParameterSpec(ivBytes);
    }

    public String getInitializationVector() {
        return Base64.getUrlEncoder().encodeToString(this.ivParameterSpec.getIV());
    }

    private static SecretKeySpec getSecretKey(String password) {
        try {
            return new SecretKeySpec(password.getBytes(UTF_8), ALGORITHM);
        } catch (UnsupportedEncodingException e) {
            Logger.getRootLogger().error("Unsupported encoding algorithm! ", e);
            return null;
        }
    }

}

我尝试了很多东西,它没有给出与 java 类相同的结果,但最常见的解决方案是:

$iv  = base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES-128-CBC')));

$encodedEncryptedData = base64_encode(openssl_encrypt($string, "AES-128-CBC", $key, OPENSSL_RAW_DATA, base64_decode($iv)));

我也尝试过使用相同的 IV(固定),但它也不起作用......

我想念一些东西,但我不知道是什么。

提前谢谢

标签: javaphpencryptionaes

解决方案


谢谢@Michael

我使用这些功能:

    function base64url_encode( $data ){
        return rtrim( strtr( base64_encode( $data ), '+/', '-_'), '=');
    }

    function base64url_decode( $data ){
        return base64_decode( strtr( $data, '-_', '+/') . str_repeat('=', 3 - ( 3 + strlen( $data )) % 4 ));
    }

而不是 base64_encode 和 base64_decode


推荐阅读