PHP7 使用OpenSSL进行AES加密与android互通

由于网上的代码大部分过于老旧并且很多雷同的文章,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;
        }
    }
}

 

你可能感兴趣的:(PHP7 使用OpenSSL进行AES加密与android互通)