当前位置: 首页 > 知识库问答 >
问题:

使用Java和PHP的AES CBC 128位加密

万俟震博
2023-03-14

我最近在Java中使用了AES CBC 128算法来加密数据。现在我需要用PHP重建算法,但我不知道如何重建,因为互联网上的PHP算法返回不同的结果。也许你能帮我。

这是要加密的Java代码:

private SecretKeySpec secretKey;
private IvParameterSpec ivSpec;

public void setKey(String myKey) {
    MessageDigest sha = null;
    try {
        byte[] key = myKey.getBytes("UTF-8");
        sha = MessageDigest.getInstance("SHA-1");
        key = sha.digest(key);
        key = Arrays.copyOf(key, 16);
        secretKey = new SecretKeySpec(key, "AES");

        byte[] iv = new String("1010101010101010").getBytes("UTF-8");
        ivSpec = new IvParameterSpec(iv);

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

public String encrypt(String strToEncrypt) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        return Base64.encode(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public String decrypt(String strToDecrypt) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        return new String(cipher.doFinal(Base64.decode(strToDecrypt)));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static void main(String[] args) {

    AESText aes = new AESText();
    final String secretKey = "com.secure.test.projectjasdS/FjkGkGhkGjhG786Vjfg=tjGFGH";
    aes.setKey(secretKey);

    String originalString = "test set se ts et set s et se";
    String encryptedString = aes.encrypt(originalString);
    String decryptedString = aes.decrypt(encryptedString);

    System.out.println("origin: " + originalString);
    System.out.println("encrypted: " + encryptedString);
    System.out.println("decrypted: " + decryptedString);
}

这是我的php代码:

    protected $key;
    protected $method = 'AES-128-CBC';
    protected $iv = '1010101010101010';
    protected $option = OPENSSL_CIPHER_AES_128_CBC;

    function __construct($key)
    {
        $this->key = $key;
    }

    public function encrypt($data) {
        if (is_null($data)) {
            return "Error " . INVALID_PARAMS_ENCRYPTIONS . ": Data is null ";
        }
        $enc = openssl_encrypt($data, $this->method, $this->key, $this->option, $this->iv);
        return base64_encode($enc);
    }

    public function decrypt($data) {
        if (is_null($data)) {
            return "Error " . INVALID_PARAMS_ENCRYPTIONS . ": Data is null ";
        }
        $data = base64_decode($data);
        $dec = openssl_decrypt($data, $this->method, $this->key, $this->option, $this->iv);
        return $dec;
    }

当我从java加密加密数据时,此结果无法在Php解密上解密。

你们能帮我构建一个PHP脚本吗?它可以返回与java加密相同的结果?

共有1个答案

吴德辉
2023-03-14

乍一看,这里有三个问题:

首先:你没有使用相同的模式:在java中你有AES/ECB/PKCS5Padd,而你的php使用AES-128-CBC

第二:在Java和PHP代码中,您可能没有使用相同的IV(IV与ECB无关,但一旦您将Java切换到CBC,您将需要它):

php中有$iv='1010101010101010'(然后传递给openssl),但java中没有类似的内容。

至少,你可能也需要这样的东西在你的Java部分:

cipher.init(Cipher.DECRYPT_MODE/ENCRYPT_MODE, secretKey, new IvParameterSpec(iv))

iv是一个包含iv字节的字节[]

第三:一旦解决了上面的问题,填充可能是下一个突破性的事情:你的java密码规范提到了PKCS5Padd。你需要确保你的两个对手使用相同的。

编辑:第四:还有一个问题是如何导出要使用的关键位。在java中,获取sha1散列的前16个字节,在php中,只需将$key传递给openssl。openssl可能以另一种方式派生加密密钥。

当使用分组密码构建与密码学相关的工具时,重温诸如分组密码操作模式和维基百科上的填充之类的经典知识总是很好的,以了解幕后发生了什么。

 类似资料:
  • 问题内容: 我一直在寻找在PHP服务器和Java客户端之间加密数据的方法。单独地,代码工作正常,我想在PHP服务器上坚持使用OpenSSL。 在尝试解码PHP加密字符串时遇到错误时,您是否看到了我所缺少的任何内容: PHP: PHP输出: 加密之前:Hello World !!! 在Base64之前:SGVsbG8gV29ybGQhISE = 加密镜头:44 加密的b64:U21yMVRGQTdR

  • 问题内容: 我正在制作一个需要基于Java的AES加密和基于JavaScript的解密的应用程序。我正在使用以下代码作为基本形式进行加密。 我试图用来解密的JavaScript是 但是JavaScript解密无法正常工作。我是新手,有人可以告诉我一种无需更改Java代码块即可解决的方法吗? 我尝试使用Base-64解码文本,如下所示: 但还是不好 我尝试了以下建议的解决方案来解决可能的填充问题,但

  • 问题内容: 有人要求我用PHP解密使用以下Java类加密的字符串。 我不懂Java,因此我需要一些帮助来理解这种加密。 1)这行是什么意思? 2)我应该为第一个参数使用什么值 3)什么时候应该在我的php脚本中使用MD5? 问题答案: 1)它创建用于基于密码的加密的参数,哈希计算中包含的盐和哈希算法执行的迭代次数(在其自身的输出中)。它用于击退彩虹表攻击,基本上,攻击者必须经过相同的迭代次数才能检

  • 加密有三个阶段: 生成16字节随机数据作为CBC模式所需的初始向量(IV) 应用AES密码,使用PKCS5填充方案在CBC模式下加密文件内容。 应用MAC密码(例如“HMACSHA1”)来计算封装IV和密文的MAC 加密文件将是以下数据的级联:16字节IV密文20字节HMAC 我写的代码是这样的,它成功地加密了一个文本文件。这是我的应用程序的全部代码。

  • 问题内容: 我有做乘法和加法的方法,但是我只是无法理解它们。它们都是来自外部网站,而不是我自己的: 我尝试进行逐步调试,但是对我来说确实没有多大意义,尽管它可以工作。 我可能正在寻找的是尝试并了解其工作原理(也许是数学基础?)。 编辑:这不是家庭作业,我只是想学习Java中的按位运算。 问题答案: 让我们开始看乘法代码。这个想法实际上很聪明。假设您有以二进制形式编写的n 1和n 2。然后,您可以将

  • 这几天我一直在纠结。我需要使用一个接受加密参数的API。API是用C#编写的。请求的加密如下: 算法:AES 密码模式:CBC 填充模式:PKCS7 块大小:128 密钥大小:256 加密字符串的表示形式:Base64 在搜索和尝试了网上建议的那么多东西之后,我仍然无法生成相同的加密值(特别是默认情况下不支持PKCS7,而PKCS5应该工作相同,但事实并非如此)。以下是我尝试过的一些方法: 1)使