简体   繁体   English

将PHP openssl_decrypt / encrypt =>转换为Java AES 256

[英]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. 对于一个项目,我必须用Java翻译PHP功能openssl_decrypt和openssl_encrypt。

The PHP fonctions are called like that : PHP函数的名称如下:

$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 : with cryptedFieldName =要加密或解密的字符串,并且:

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

So, I translated the previous PHP code into the following Java code : 因此,我将之前的PHP代码转换为以下Java代码:

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. 我的Java代码可以正常工作,但是我不确定它是否完全与openssl_decrypt和openssl_encrypt背后的代码相对应。 For instance a salt is not needed in PHP but mandatory in my Java functions. 例如,在PHP中不需要盐,但在Java函数中则是必需盐。

What do you think of my code ? 您如何看待我的代码? Is it possible to add a Salt parameter in the PHP function ? 是否可以在PHP函数中添加Salt参数? 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 ? 最后,我的主要问题是:我对PHP函数的翻译对您来说是否正确,我应该对我的多余的和必填的salt参数做什么? Thanks. 谢谢。

I really don't know why you implemented PBKDF2 in Java. 我真的不知道为什么要用Java实现PBKDF2。 That's nowhere near what openssl_encrypt is doing. 那离openssl_encrypt正在做什么openssl_encrypt 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. 实际上,如果您已经阅读了文档中的第一条评论 ,那么您应该已经知道pass参数实际上是密钥,而不是某种密码。 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" 如果要AES-256(这是“哈希”的前32个字节),则需要为openssl_encrypt提供一个32字节的密钥: “ GzH7vYfW2mp4TZKFx2UKuFvk4nPWy6KZ”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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