PHP和Java之间的加密

我当时希望加密PHP服务器和Java客户端之间的数据。 单独的代码工作正常,我想在PHP服务器上坚持使用OpenSSL。

当你在尝试解码PHP加密字符串时遇到错误时,你们中是否有人看到我在这里丢失的任何内容:

[删除非工作代码]

更新 – 我能够使用openssl。 这是使用PHP和Java文件的GIT repo。

https://github.com/chaudhuri-ab/CrossPlatformCiphers

我无法弄清楚你的方法失败的原因。 顺便说一句,这是我做的,

Java的

import com.sun.org.apache.xml.internal.security.utils.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.security.Key; public class MyClass { public static void main(String[] args) { String data = "Arnab C"; final String enc = DarKnight.getEncrypted(data); System.out.println("Encrypted : " + enc); System.out.println("Decrypted : " + DarKnight.getDecrypted(enc)); } static class DarKnight { private static final String ALGORITHM = "AES"; private static final byte[] SALT = "tHeApAcHe6410111".getBytes();// THE KEY MUST BE SAME private static final String X = DarKnight.class.getSimpleName(); static String getEncrypted(String plainText) { if (plainText == null) { return null; } Key salt = getSalt(); try { Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, salt); byte[] encodedValue = cipher.doFinal(plainText.getBytes()); return Base64.encode(encodedValue); } catch (Exception e) { e.printStackTrace(); } throw new IllegalArgumentException("Failed to encrypt data"); } public static String getDecrypted(String encodedText) { if (encodedText == null) { return null; } Key salt = getSalt(); try { Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, salt); byte[] decodedValue = Base64.decode(encodedText); byte[] decValue = cipher.doFinal(decodedValue); return new String(decValue); } catch (Exception e) { e.printStackTrace(); } return null; } static Key getSalt() { return new SecretKeySpec(SALT, ALGORITHM); } } } 

PHP

  

Java输出

加密:PJG1Uu6SjJuuVGf7ApuHAw ==

解密:Arnab C.

PHP输出

加密:PJG1Uu6SjJuuVGf7ApuHAw ==

解密:Arnab C.

可以找到工作版本 – https://github.com/chaudhuri-ab/CrossPlatformCiphers

需要记住的一点是,如果您未在PHP中指定OPENSSL_RAW_DATA,则数据将被加密为base64。 那让我失望了。

PHP:

 class PHP_AES_Cipher { private static $OPENSSL_CIPHER_NAME = "aes-128-cbc"; //Name of OpenSSL Cipher private static $CIPHER_KEY_LEN = 16; //128 bits /** * Encrypt data using AES Cipher (CBC) with 128 bit key * * @param type $key - key to use should be 16 bytes long (128 bits) * @param type $iv - initialization vector * @param type $data - data to encrypt * @return encrypted data in base64 encoding with iv attached at end after a : */ static function encrypt($key, $iv, $data) { if (strlen($key) < PHP_AES_Cipher::$CIPHER_KEY_LEN) { $key = str_pad("$key", PHP_AES_Cipher::$CIPHER_KEY_LEN, "0"); //0 pad to len 16 } else if (strlen($key) > PHP_AES_Cipher::$CIPHER_KEY_LEN) { $key = substr($str, 0, PHP_AES_Cipher::$CIPHER_KEY_LEN); //truncate to 16 bytes } $encodedEncryptedData = base64_encode(openssl_encrypt($data, PHP_AES_Cipher::$OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, $iv)); $encodedIV = base64_encode($iv); $encryptedPayload = $encodedEncryptedData.":".$encodedIV; return $encryptedPayload; } /** * Decrypt data using AES Cipher (CBC) with 128 bit key * * @param type $key - key to use should be 16 bytes long (128 bits) * @param type $data - data to be decrypted in base64 encoding with iv attached at the end after a : * @return decrypted data */ static function decrypt($key, $data) { if (strlen($key) < PHP_AES_Cipher::$CIPHER_KEY_LEN) { $key = str_pad("$key", PHP_AES_Cipher::$CIPHER_KEY_LEN, "0"); //0 pad to len 16 } else if (strlen($key) > PHP_AES_Cipher::$CIPHER_KEY_LEN) { $key = substr($str, 0, PHP_AES_Cipher::$CIPHER_KEY_LEN); //truncate to 16 bytes } $parts = explode(':', $data); //Separate Encrypted data from iv. $decryptedData = openssl_decrypt(base64_decode($parts[0]), PHP_AES_Cipher::$OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, base64_decode($parts[1])); return $decryptedData; } } 

Java的:

 package ciphers; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class Java_AES_Cipher { private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING"; private static int CIPHER_KEY_LEN = 16; //128 bits /** * Encrypt data using AES Cipher (CBC) with 128 bit key * * * @param key - key to use should be 16 bytes long (128 bits) * @param iv - initialization vector * @param data - data to encrypt * @return encryptedData data in base64 encoding with iv attached at end after a : */ public static String encrypt(String key, String iv, String data) { try { if (key.length() < Java_AES_Cipher.CIPHER_KEY_LEN) { int numPad = Java_AES_Cipher.CIPHER_KEY_LEN - key.length(); for(int i = 0; i < numPad; i++){ key += "0"; //0 pad to len 16 bytes } } else if (key.length() > Java_AES_Cipher.CIPHER_KEY_LEN) { key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes } IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector); byte[] encryptedData = cipher.doFinal((data.getBytes())); String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData); String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("UTF-8")); return base64_EncryptedData + ":" + base64_IV; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * Decrypt data using AES Cipher (CBC) with 128 bit key * * @param key - key to use should be 16 bytes long (128 bits) * @param data - encrypted data with iv at the end separate by : * @return decrypted data string */ public static String decrypt(String key, String data) { try { String[] parts = data.split(":"); IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1])); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]); byte[] original = cipher.doFinal(decodedEncryptedData); return new String(original); } catch (Exception ex) { ex.printStackTrace(); } return null; } } 

我使用了theapache64中的解决方案,但是在PHP 7.2中它已经停止工作,因为Mcrypt已经被弃用并且后来被删除了。 所以我改变了代码,它的工作原理:

 function encrypt($data, $key) { return base64_encode(openssl_encrypt($data, "aes-128-ecb", $key, OPENSSL_RAW_DATA)); } function decrypt($data, $key) { return openssl_decrypt(base64_decode($data), "aes-128-ecb", $key, OPENSSL_RAW_DATA); }