Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP OpenSSL将Java AES/ECB/PKCS7Padding/代码转换为PHP_Java_Php_Encryption_Cryptography_Aes - Fatal编程技术网

使用PHP OpenSSL将Java AES/ECB/PKCS7Padding/代码转换为PHP

使用PHP OpenSSL将Java AES/ECB/PKCS7Padding/代码转换为PHP,java,php,encryption,cryptography,aes,Java,Php,Encryption,Cryptography,Aes,我想使用AES 256位加密算法和ECB和PKCS7Padding对字符串进行加密。我去过很多地方,但没有一个是合适的 我有一个Java代码,它使用AES/ECB/PKCS7Padding方法来加密字符串 输入:“mystring” 输出:sWVnDZ0dwiTYoK4ixtURdA== 我希望这个算法在PHP中使用OpenSSL,我已经尝试了很多解决方案,但没有一个适合我 请帮我解决这个问题 JAVA代码 package com.test.utils; import com.sun.or

我想使用AES 256位加密算法和ECB和PKCS7Padding对字符串进行加密。我去过很多地方,但没有一个是合适的

我有一个Java代码,它使用AES/ECB/PKCS7Padding方法来加密字符串

输入:“mystring” 输出:sWVnDZ0dwiTYoK4ixtURdA==

我希望这个算法在PHP中使用OpenSSL,我已经尝试了很多解决方案,但没有一个适合我

请帮我解决这个问题

JAVA代码

package com.test.utils;



import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import java.security.Key;
import java.security.Security;

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

public class Crypto {

    private final String ALGORITHM = "AES/ECB/PKCS7Padding";
    private byte[] keyValue;

    public Crypto(String token) {
        keyValue = token.getBytes();
    }

    public Crypto() {
        keyValue= new byte[]{1, 2, 3, 4, 5, 6, 7,8,9, 10, 11, 12,13, 14, 15, 16};
    }

    public String encrypt(String valueToEnc) throws Exception {

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        Key key = generateKey();

        Cipher c = Cipher.getInstance(ALGORITHM, "BC");
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encValue = c.doFinal(valueToEnc.getBytes("UTF8"));
        return Base64.encode(encValue);

    }

    public String decrypt(String encryptedValue) throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGORITHM, "BC");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = Base64.decode(encryptedValue);
        byte[] decValue = c.doFinal(decordedValue);
        return new String(decValue);
    }


    private Key generateKey() throws Exception {
        return new SecretKeySpec(keyValue, ALGORITHM);
    }
}
我已经尝试过使用OpenSSL在php中进行操作

<?php
$data = "mystring";
$method = "AES-256-ECB";
$ivSize = openssl_cipher_iv_length($method);

$iv = [1, 2, 3, 4, 5, 6, 7,8,9, 10, 11, 12,13, 14, 15, 16];

$packed = call_user_func_array("pack", array_merge(array("c*"), $iv));

$output_utf8 = mb_convert_encoding($packed, 'utf-8');
$encrypted = openssl_encrypt($data,$method,$output_utf8,OPENSSL_RAW_DATA);



echo strlen('sWVnDZ0dwiTYoK4ixtURdA==');
echo "<br>";
echo "Expected Answer : sWVnDZ0dwiTYoK4ixtURdA==<br><br>";
echo strlen(base64_encode($encrypted));
echo "<br>";
echo "Answer : ".base64_encode($encrypted);

?>

预期答案:sWVnDZ0dwiTYoK4ixtURdA==


实际答案:7e5sKRCi21xzcwo6+ZOfaA==

这里有两个问题

首先,在Java中,使用的AES变体(128、192或256)由密钥的长度决定。这里您使用的是一个16字节或128位的密钥,因此您使用的是AES-128

在PHP中,直接指定AES变量,并且指定AES-256。PHP将简单地使用空字节扩展密钥,直到达到所需的长度。如果要匹配Java代码,则应指定
AES-128-ECB

其次,您需要注意如何处理密钥。在PHP代码中,实际上使用的是一个全部为空字节的键,因为
pack
对字符串的处理方式与您期望的不同。您只需使用将数组转换为字符串:

$encrypted = openssl_encrypt($data, $method, implode($iv), OPENSSL_RAW_DATA);