Prpcrypt.php 3.2 KB

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