PHP实现AES对称加密

背景

在开发支付宝小程序时,获取用户手机号,需要AES解密得到手机号明文。
官方并没有提供PHP解密的实例,所以要用PHP实现AES算法的解密过程。

要点

  1. PHP实现AES解密可以用 mcrypt 类方法,以及 openssl 族的方法。mcrypt 在PHP7.2被弃用,所以推荐使用 openssl 实现。
  2. screct_key 即 aes_key 是从支付宝小程序管理中心后台获取的。

实现过程

openssl 实现方式

/**
	 * openssl 解密
	 * @param unknown $encryptedData
	 * @return string
	 */
	protected static function decryptOpenssl($encryptedData, $screct_key) {
		$aesKey = base64_decode($screct_key);
		$aesIV = null;
		$aesCipher = base64_decode($encryptedData);
		$result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); //1=OPENSSL_RAW_DATA 模式
// 		$result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 2, $aesIV);
		return $result;
	}

options 参数即为重要,它是兼容 mcrpty 算法的关键:

options = 0: 默认模式,自动对明文进行 pkcs7 padding,且数据做 base64 编码处理。
options = 1: OPENSSL_RAW_DATA,自动对明文进行 pkcs7 padding, 且数据未经 base64 编码处理。这里的理解很重要
options = 2: OPENSSL_ZERO_PADDING,要求待加密的数据长度已按 "0" 填充与加密算法数据块长度对齐,即同 mcrpty 默认填充的方式一致,且对数据做 base64 编码处理。注意,此模式下 openssl 要求待加密数据已按 "0" 填充好,其并不会自动帮你填充数据,如果未填充对齐,则会报错。

mcrypt 实现方式,可以参考alipay sdk 的aop/AopEnctypt.php 的 decrypt

class AliBizDataCrypt {
	 * 解密方法
	 *
	 * @param string $encryptedData : 需要解密的报文
	 * @return string
	 */
	protected static function decrypt($encryptedData, $screct_key) {
		// AES, 128 模式加密数据 CBC
		$encryptedDataBase64Decoded = base64_decode($encryptedData);
		$screct_key = base64_decode($screct_key);
		// 设置全0的IV
		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
		$iv = str_repeat("", $iv_size);
		$decrypt_str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $screct_key, $encryptedDataBase64Decoded, MCRYPT_MODE_CBC, $iv);
		$decrypt_str = self::stripPKSC7Padding($decrypt_str);
		return $decrypt_str;
	}
	
	/**
	 * 移去填充算法
	 *
	 * @param string $source
	 * @return string
	 */
	protected static function stripPKSC7Padding($source) {
		$char = substr($source, - 1);
		$num = ord($char);
		if( $num == 62 )
			return $source;
		$source = substr($source, 0, - $num);
		return $source;
	}
}	
原文地址:https://www.cnblogs.com/aworkstory/p/php-aes-symmetrical-encryption.html