PHP的翻译openssl_decrypt / encrypt =>到Java AES 256

时间:2015-11-21 11:26:18

标签: java encryption aes

对于一个项目,我必须在Java中翻译PHP功能openssl_decrypt和openssl_encrypt。

PHP函数的调用方式如下:

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

或:

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

with cryptedFieldName =要加密或解密的字符串,并且:

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

因此,我将以前的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);
    }
}

主要课程:

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

我的Java代码有效,但我不确定它是否与openssl_decrypt和openssl_encrypt背后的代码完全对应。 例如,PHP中不需要salt,但我的Java函数中是必需的。

您如何看待我的代码?是否可以在PHP函数中添加Salt参数?那么,它会产生相同的结果吗?我的主要问题是:我的PHP函数的翻译似乎对你来说是正确的,我应该对我的额外和强制性额外的salt参数做些什么? 感谢。

1 个答案:

答案 0 :(得分:0)

我真的不知道你为什么在Java中实现PBKDF2。这远远不及openssl_encrypt正在做的事情。实际上,如果你已经阅读了文档中的first comment,你应该已经看到pass参数实际上是关键而不是某种密码。如果你想要AES-256,你需要提供一个32字节的密钥到openssl_encrypt,这将是你的“哈希”的前32个字节:“GzH7vYfW2mp4TZKFx2UKuFvk4nPWy6KZ”