由于网上的代码大部分过于老旧并且很多雷同的文章,PHP加密部分基本都是基于mcrypt_xxx之类函数的代码,但是这类函数php7以后已经被移除了,导致折腾了10几个钟,总算使加密结果一致了,简单记录下,希望能帮到有需要的朋友。
注意以下几点就可以了:
1、java部分加密算法使用:AES/CBC/PKCS5Padding
2、客户端和服务端的key和IV的长度应该为16
3、java端的key不要使用KeyGenerator进行强化,那样会导致无法跨平台
废话不多说,来看代码~
PHP部分,这个其实也适用所有php版本:
class AESUtils {
//key长度应该为16
public static $key = "rb!nBwXv4C%Gr^84";
//iv长度应该为16
public static $iv = "1234567812345678";
//配合Java端,使用128位,256位java端默认是不支持的
public static $Method = 'AES-128-CBC';
/**
* AES加密
*
* 可传入自定义密码
*
* $key
*/
public static function encrypt($cleartext,$key = ''){
$key = empty($key) ? self::$key : $key;
$encrypted = openssl_encrypt($cleartext, self::$Method, $key, OPENSSL_RAW_DATA, self::$iv);
return base64_encode($encrypted);
}
/**
* AES解密
*
* 可传入自定义密码
*
* $key
*/
public static function decrypt($encrypted,$key = ''){
$key = empty($key) ? self::$key : $key;
$encrypted = base64_decode($encrypted);
$decrypted = openssl_decrypt($encrypted, self::$Method, $key, OPENSSL_RAW_DATA, self::$iv);
return trim($decrypted);
}
}
java端:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
//IV长度应该为16,请跟服务端保持一致
private static final String iv = "1234567812345678";
//AES/CBC/PKCS5Padding默认对应PHP则为:AES-128-CBC
private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
private static final String AES = "AES";//AES 加密
/**
*
* @param key 这个key长度应该为16位,另外不要用KeyGenerator进行强化,否则无法跨平台
* @param cleartext
* @return
*/
public static String encrypt(String key, String cleartext){
try {
Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), AES);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(cleartext.getBytes());
//base64编码一下
return Base64Encoder.encode(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decrypt(String key, String encrypted){
try
{
byte[] encrypted1 = Base64Decoder.decodeToBytes(encrypted);
Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), AES);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
//转换为字符串
return new String(original);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
}