微信公众号加密之踩坑

在微信公众号中 微信与服务器通信 有一个安全模式 如下图

我们看看微信自带的sdk 核心解密部分 然而这个 mcrypt_encrypt  在 php7.1.* 中 函数已经不允许使用



那么问题来了 php7 速度极快 怎么才能用呢  我将微信sdk 的解密部分合并到了一个文件 如下 使用了 

openssl_decrypt

替换了mcrypt_encrypt  


<?php
namespace Crypt;

class WxCrypt{
	private $token;
	private $encodingAesKey;
	private $appId;
	public function __construct($token, $encodingAesKey, $appId)
	{
		$this->token = $token;
		$this->encodingAesKey = $encodingAesKey;
		$this->appId = $appId;
	}
	
	// 微信解密
	function decode($data){
		$timestamp  = input('param.timestamp/s') ;
		$nonce = input('param.nonce/s');
		$msg_signature  = input('param.msg_signature/s');
		$encrypt_type =input('param.encrypt_type/s');
		Filelog("=========\r\n{$data}========\r\n 时间戳{$timestamp}\r\n随机数{$nonce} \r\n签名{$msg_signature} \r\n加密类型 {$encrypt_type}");
		//提取xml
		try {
			$xml = new \DOMDocument();
			$xml->loadXML($data);
			$array_e = $xml->getElementsByTagName('Encrypt');
			$array_a = $xml->getElementsByTagName('ToUserName');
			$encrypt = $array_e->item(0)->nodeValue;
			$touser_name = $array_a->item(0)->nodeValue;
			Filelog('xml提取成功');
			
		} catch (Exception $e) {
			Filelog('xml提取失败');
			exit();
		}
		
		//排序加密验证签名是否准确
		try {
			$array = array($encrypt, $this->token, $timestamp, $nonce);
			sort($array, SORT_STRING);
			$str = implode($array);
			$signature=sha1($str);
			Filelog('加密成功');
			if($signature!=$msg_signature){
				Filelog('秘钥不符');
				exit();
			}else {
				Filelog('秘钥相符');
			}
		} catch (Exception $e) {
			Filelog('排序加密失败');
			exit();
		}
		
		//对称解密内容
		try {
			//使用BASE64对需要解密的字符串进行解码
			Filelog('开始解密1');
			$ciphertext_dec = base64_decode($encrypt);			
			$key= base64_decode($this->encodingAesKey . "=");
			$iv = substr($key, 0, 16);
			$xml=openssl_decrypt(base64_decode($encrypt), "aes-256-cbc", $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
// 			$rxml=substr($xml, 20,strlen($xml)-(20+strlen($this->appId)));
			
			$content = substr($xml, 16, strlen($xml));
			$len_list = unpack("N", substr($content, 0, 4));
			$xml_len = $len_list[1];
			Filelog("长度".$xml_len);
			$rxml = substr($content, 4, $xml_len);
			
			Filelog("解密成功\r\n".$rxml);
			return $rxml;
		} catch (Exception $e) {
			Filelog('解密失败');
			exit();
		}

		return  '';
		
	}
}

到此完美解决!

如有疑问欢迎加 QQ群 564656678 探讨 

如有帮助欢迎捐赠


猜你喜欢

转载自blog.csdn.net/meimx/article/details/79358324