2015-11-21 190 views
0

对于一个项目,我必须在Java中翻译PHP函数openssl_decrypt和openssl_encrypt。翻译PHP openssl_decrypt/encrypt =>到Java AES 256

的PHP fonctions被称为这样的:

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

与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中不需要盐,但在我的Java函数中必须使用salt。

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

回答

0

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

+0

嗨!谢谢您的回答。对于我不知道的PBKDF2,我认为这是AES256中的一种标准:[链接](http://karanbalkar.com/2014/02/tutorial-76-implement-aes-256-encryptiondecryption-使用-java /)或[链接](http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption)我应该使用什么?好吧,对于32位散列,我不知道为什么PHP开发人员需要这样一个长键。我只是在这里用Java来翻译这个东西...... –

+0

好吧,如果你使用真正的密码而不是随机生成的密钥进行加密,那么使用PBKDF2进行大量迭代(超过100,000次)是一个好主意,和一个随机盐(可以放在密文旁边)从密码派生密钥。这只是你的PHP代码中没有发生的事情。我强烈建议您考虑更改PHP代码以使用PBKDF2。 –

+0

请记住,您应该为您的密文添加身份验证,以检测传输中密文的(恶意)操作。如果您可以更改PHP代码,那么我可以推荐[RNCryptor-php](https://github.com/RNCryptor/RNCryptor-php),它也有一个[Java版本(JNCryptor)](https:// github。 com/RNCryptor/JNCryptor)并且应该兼容。 –