简体   繁体   中英

Translation of PHP openssl_decrypt/encrypt => to Java AES 256

For a project, I have to translate in Java the PHP fonctions openssl_decrypt and openssl_encrypt.

The PHP fonctions are called like that :

$cryptedValue = openssl_encrypt($dataSet[$cryptedFieldName], $this->getCryptOption('method'), $this->getCryptOption('hash'), false, $this->getCryptOption('vector'));

or :

$uncryptedValue = openssl_decrypt($dataSet[$cryptedFieldName], $this->getCryptOption('method'), $this->getCryptOption('hash'), false, $this->getCryptOption('vector'));

with cryptedFieldName = the String to crypt or decrypt and :

'method' = 'aes-256-cfb'
'hash' = 'GzH7vYfW2mp4TZKFx2UKuFvk4nPWy6KZyPSALFePVsWZp8kHhqDHfheZEABB5FAUdYQzbL25sPU9PbjHVHw8QgR2E832rHPKu9bV2HRzxLFWXV85j6CSGMeGpLks9duv'
'vector' = 'zvChhBgQ16yCBghn'

So, I translated the previous PHP code into the following Java code :

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.Charset;
import java.lang.reflect.Field;

public class Cryptage_EAS {

    public String decrypt(String encryptedText, String salt, String hash, String vector) throws Exception {

        // Autoriser le cryptage EAS 256
        try {
            Field field = Class.forName("javax.crypto.JceSecurity").
            getDeclaredField("isRestricted");
            field.setAccessible(true);
            field.set(null, java.lang.Boolean.FALSE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // Set en tableau de byte des différentes entrées
        byte[] vectorBytes = vector.getBytes(Charset.forName("UTF-8"));
        byte[] saltBytes = salt.getBytes(Charset.forName("UTF-8"));
        byte[] encryptedTextBytes = Base64.decodeBase64(encryptedText);

        // Création de la clé
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(hash.toCharArray(), saltBytes, 1, 256);
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        // Décryptage
        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(vectorBytes));

        return new String(cipher.doFinal(encryptedTextBytes), "UTF-8");
    }

    public String encrypt(String textToCrypt, String salt, String hash, String vector) throws Exception {  

        // Autoriser le cryptage EAS 256
        try {
            Field field = Class.forName("javax.crypto.JceSecurity").
            getDeclaredField("isRestricted");
            field.setAccessible(true);
            field.set(null, java.lang.Boolean.FALSE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // Set en tableau de byte des différentes entrées
        byte[] vectorBytes = vector.getBytes(Charset.forName("UTF-8"));
        byte[] saltBytes = salt.getBytes(Charset.forName("UTF-8"));

        // Création de la clé
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(hash.toCharArray(), saltBytes, 1, 256);
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        // Cryptage
        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(vectorBytes));
        byte[] encryptedTextBytes = cipher.doFinal(textToCrypt.getBytes("UTF-8"));

        return new Base64().encodeAsString(encryptedTextBytes);
    }
}

For the main class :

Cryptage_EAS c_EAS = new Cryptage_EAS();
String hash = "GzH7vYfW2mp4TZKFx2UKuFvk4nPWy6KZyPSALFePVsWZp8kHhqDHfheZEABB5FAUdYQzbL25sPU9PbjHVHw8QgR2E832rHPKu9bV2HRzxLFWXV85j6CSGMeGpLks9duv";
String salt = "SelDeMerFin";
String vector = "zvChhBgQ16yCBghn";
String strToCrypt = "The Answer Is 42";
String encryptedText = c_EAS.encrypt(strToCrypt, salt, hash, vector);
System.out.println("Encrypted : "+c_EAS.encrypt(strToCrypt, salt, hash, vector));
System.out.println("Decrypted : "+c_EAS.decrypt(encryptedText, salt, hash, vector));

My Java code works but I am not sure that it corresponds exactly to what is coded behind openssl_decrypt and openssl_encrypt. For instance a salt is not needed in PHP but mandatory in my Java functions.

What do you think of my code ? Is it possible to add a Salt parameter in the PHP function ? Then, will it produce the same result ? My major question is finally : is my translation of the PHP functions seems to be correct for you and what am I supposed to do to my extra and mandatory extra salt parameter ? Thanks.

I really don't know why you implemented PBKDF2 in Java. That's nowhere near what openssl_encrypt is doing. In fact, if you've read the first comment in the documentation, you should have seen that the pass parameter is actually the key and not some kind of password. You need to provide a 32 byte key to openssl_encrypt if you want AES-256 which will be the first 32 bytes of your "hash": "GzH7vYfW2mp4TZKFx2UKuFvk4nPWy6KZ"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM