對於一個項目,我必須在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函數的翻譯似乎對你來說是正確的,我應該怎麼做我的額外和必需的額外鹽參數? 謝謝。
嗨!謝謝您的回答。對於我不知道的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來翻譯這個東西...... –
好吧,如果你使用真正的密碼而不是隨機生成的密鑰進行加密,那麼使用PBKDF2進行大量迭代(超過100,000次)是一個好主意,和一個隨機鹽(可以放在密文旁邊)從密碼派生密鑰。這只是你的PHP代碼中沒有發生的事情。我強烈建議您考慮更改PHP代碼以使用PBKDF2。 –
請記住,您應該爲您的密文添加身份驗證,以檢測傳輸中密文的(惡意)操作。如果您可以更改PHP代碼,那麼我可以推薦[RNCryptor-php](https://github.com/RNCryptor/RNCryptor-php),它也有一個[Java版本(JNCryptor)](https:// github。 com/RNCryptor/JNCryptor)並且應該兼容。 –