Reputation: 397
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
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