Prpcrypt.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace app\lib\wx_encode;
  3. /**
  4. * Prpcrypt class
  5. *
  6. * 提供接收和推送给公众平台消息的加解密接口.
  7. */
  8. class Prpcrypt
  9. {
  10. public $key;
  11. function __construct($k)
  12. {
  13. $this->key = base64_decode($k . "=");
  14. }
  15. /**
  16. * 对明文进行加密
  17. * @param string $text 需要加密的明文
  18. * @param $appid
  19. * @return array 加密后的密文
  20. */
  21. public function encrypt($text, $appid)
  22. {
  23. try {
  24. //获得16位随机字符串,填充到明文之前
  25. $random = $this->getRandomStr();
  26. $text = $random . pack("N", strlen($text)) . $text . $appid;
  27. // 网络字节序
  28. // $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
  29. // $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  30. $iv = substr($this->key, 0, 16);
  31. //使用自定义的填充方式对明文进行补位填充
  32. $pkc_encoder = new PKCS7Encoder;
  33. $text = $pkc_encoder->encode($text);
  34. // mcrypt_generic_init($module, $this->key, $iv);
  35. //加密
  36. $encrypted = openssl_encrypt($text, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
  37. // mcrypt_generic_deinit($module);
  38. // mcrypt_module_close($module);
  39. //print(base64_encode($encrypted));
  40. //使用BASE64对加密后的字符串进行编码
  41. return array(ErrorCode::$OK, base64_encode($encrypted));
  42. } catch (\Exception $e) {
  43. //print $e;
  44. return array(ErrorCode::$EncryptAESError, null);
  45. }
  46. }
  47. /**
  48. * 对密文进行解密
  49. * @param string $encrypted 需要解密的密文
  50. * @param $appid
  51. * @return array|string
  52. */
  53. public function decrypt($encrypted, $appid)
  54. {
  55. try {
  56. //使用BASE64对需要解密的字符串进行解码
  57. $ciphertext_dec = base64_decode($encrypted);
  58. // $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
  59. $iv = substr($this->key, 0, 16);
  60. // mcrypt_generic_init($module, $this->key, $iv);
  61. //解密
  62. $decrypted = openssl_decrypt($ciphertext_dec, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
  63. // mcrypt_generic_deinit($module);
  64. // mcrypt_module_close($module);
  65. } catch (\Exception $e) {
  66. return array(ErrorCode::$DecryptAESError, null);
  67. }
  68. try {
  69. //去除补位字符
  70. $pkc_encoder = new PKCS7Encoder;
  71. $result = $pkc_encoder->decode($decrypted);
  72. //去除16位随机字符串,网络字节序和AppId
  73. if (strlen($result) < 16)
  74. return "";
  75. $content = substr($result, 16, strlen($result));
  76. $len_list = unpack("N", substr($content, 0, 4));
  77. $xml_len = $len_list[1];
  78. $xml_content = substr($content, 4, $xml_len);
  79. $from_appid = substr($content, $xml_len + 4);
  80. } catch (\Exception $e) {
  81. //print $e;
  82. return array(ErrorCode::$IllegalBuffer, null);
  83. }
  84. if ($from_appid != $appid)
  85. return array(ErrorCode::$ValidateAppidError, null);
  86. return array(0, $xml_content);
  87. }
  88. /**
  89. * 随机生成16位字符串
  90. * @return string 生成的字符串
  91. */
  92. function getRandomStr()
  93. {
  94. $str = "";
  95. $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  96. $max = strlen($str_pol) - 1;
  97. for ($i = 0; $i < 16; $i++) {
  98. $str .= $str_pol[mt_rand(0, $max)];
  99. }
  100. return $str;
  101. }
  102. }