Ankit S.
Ankit S.

Reputation: 397

Converting Java AES/ECB/PKCS7Padding/ code to PHP using PHP OpenSSL

I want to encrypt a string using AES 256-bit encryption algorithm with ECB and PKCS7Padding. I had gone through many sites but none of them was suitable.

I have Java code which is using AES/ECB/PKCS7Padding method to encrypt a string.

Input: 'mystring' Output: sWVnDZ0dwiTYoK4ixtURdA==

I want this algorithm in PHP using OpenSSL, I have tried many solutions but none of them works for me.

Please help me to solve the issue

JAVA CODE

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);
    }
}

I have tried doing in php using OpenSSL

<?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);

?>

Expected Answer : sWVnDZ0dwiTYoK4ixtURdA==

Actual Answer : 7e5sKRCi21xzcwo6+ZOfaA==

Upvotes: 0

Views: 3161

Answers (1)

matt
matt

Reputation: 79743

There are two issues here.

First, in Java, the variant of AES (128, 192 or 256) that is used is determined by the length of the key. Here you are using a 16 byte, or 128 bit, key so you are using AES-128.

In PHP you specify the AES variant directly, and you are specifying AES-256. PHP will simply extend the key with null bytes until it is the required length. You should specify AES-128-ECB if you want to match the Java code.

Second, you need to be careful about how you are handling your key. In your PHP code you are actually using a key of all null bytes, since pack doesn’t work on strings the way you expect. You can simply use implode to convert the array into a string:

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

Upvotes: 1

Related Questions